表单与状态管理
-
使用
useState
初始化状态-
可以通过
useState
将数据存储在组件的状态中,例如将笔记数组存储在notes
状态中。 -
初始值可以通过
props
传递,也可以直接设置为空数组等默认值。 -
示例:
javascriptconst [notes, setNotes] = useState(props.notes);
-
-
受控组件(Controlled Component)
-
通过将输入框的
value
属性绑定到组件的状态(如newNote
),实现对输入框的控制。 -
需要为输入框添加
onChange
事件处理函数,将输入框的值同步到组件状态中。 -
示例:
javascriptconst [newNote, setNewNote] = useState(''); const handleNoteChange = (event) => { setNewNote(event.target.value); }; <input value={newNote} onChange={handleNoteChange} />;
-
-
表单提交
-
为表单添加
onSubmit
事件处理函数,防止默认提交行为(event.preventDefault()
)。 -
在提交时,可以根据状态创建新对象(如笔记对象),并更新状态。
-
示例:
javascriptconst addNote = (event) => { event.preventDefault(); const noteObject = { content: newNote, date: new Date().toISOString(), important: Math.random() < 0.5, id: notes.length + 1, }; setNotes(notes.concat(noteObject)); setNewNote(''); }; <form onSubmit={addNote}>...</form>;
-
数据过滤与显示
-
条件显示数据
-
通过添加一个状态(如
showAll
)来控制显示的数据。 -
使用条件运算符(
? :
)或数组的filter
方法来筛选数据。 -
示例:
javascriptconst [showAll, setShowAll] = useState(true); const notesToShow = showAll ? notes : notes.filter(note => note.important);
-
-
切换显示状态
-
通过按钮点击事件更新状态,从而切换显示的内容。
-
示例:
javascript<button onClick={() => setShowAll(!showAll)}> show {showAll ? 'important' : 'all'} </button>;
-
练习:电话簿应用
-
添加名字
-
使用受控组件管理输入框,通过表单提交将名字添加到电话簿中。
-
示例:
javascriptconst [persons, setPersons] = useState([{ name: 'Arto Hellas' }]); const [newName, setNewName] = useState(''); const addPerson = (event) => { event.preventDefault(); const personObject = { name: newName, id: persons.length + 1 }; setPersons(persons.concat(personObject)); setNewName(''); };
-
-
防止重复添加
-
在添加名字前,检查电话簿中是否已存在该名字。
-
如果存在,使用
alert
提示用户。 -
示例:
javascriptconst addPerson = (event) => { event.preventDefault(); if (persons.some(person => person.name === newName)) { alert(`${newName} is already added to phonebook`); } else { const personObject = { name: newName, id: persons.length + 1 }; setPersons(persons.concat(personObject)); setNewName(''); } };
-
-
添加电话号码
-
为表单添加第二个输入框,用于输入电话号码。
-
示例:
javascriptconst [newNumber, setNewNumber] = useState(''); const addPerson = (event) => { event.preventDefault(); const personObject = { name: newName, number: newNumber, id: persons.length + 1 }; setPersons(persons.concat(personObject)); setNewName(''); setNewNumber(''); };
-
-
搜索功能
-
添加一个搜索输入框,用于按名字过滤电话簿。
-
使用
filter
方法实现大小写不敏感的搜索。 -
示例:
javascriptconst [searchTerm, setSearchTerm] = useState(''); const personsToShow = persons.filter(person => person.name.toLowerCase().includes(searchTerm.toLowerCase()) );
-
-
组件拆分与重构
-
将应用拆分为多个独立组件,如搜索框、添加表单、人员列表等。
-
在根组件中维护状态和事件处理函数。
-
示例:
javascriptconst App = () => { return ( <div> <h2>Phonebook</h2> <Filter ... /> <PersonForm ... /> <Persons ... /> </div> ); };
-
调试与工具
-
React DevTools
- 使用 React DevTools 查看组件的状态和属性,方便调试。
- 可以直接在 DevTools 中修改状态,观察应用的变化。
-
调试输出
-
在组件中临时渲染状态或其他变量,方便调试。
-
示例:
javascript<div>debug: {newName}</div>;
-
注意事项
- 状态更新的不可变性
- 在 React 中,状态更新必须是不可变的,不能直接修改原始状态。
- 使用数组的
concat
或对象的展开运算符等方法来创建新状态。
- 表单默认行为
- 表单提交时会触发页面刷新,需要通过
event.preventDefault()
阻止默认行为。
- 表单提交时会触发页面刷新,需要通过
- 组件定义位置
- 不要在另一个组件的定义中直接定义子组件,避免因作用域或生命周期问题导致错误。