React中如何将组件作为事件处理器传递?解决setPersons报错
问题:React重构组件时
setPersons is assigned but never used错误修复 我正在把代码重构为组件,现在要重构AddName组件,让它作为<form>(Add Info标题下方)的事件处理器。重构后导入并传递给事件处理器时,VS Code提示setPersons is assigned but never used错误,其他props没问题。我知道通常传props的方式是<AddName setPersons={setPersons}/>,但不确定这个场景是否适用,该怎么修复?
App.js 代码
import { useState } from 'react' import AddName from './components/AddName' const App = () => { const [persons, setPersons] = useState([ { name: 'Arto Hellas', number: '012-3456789', id: 1 }, { name: 'Ada Lovelace', number: '013-4567890', id: 2 }, { name: 'Dan Abramov', number: '011-1234567', id: 3 }, { name: 'Mary Poppendieck', number: '016-5556789', id: 4 } ]) const [newName, setNewName] = useState('') const [newNumber, setNewNumber] = useState('') const [searchTerm, setSearchTerm] = useState("") const handleNameChange = (event) => { setNewName(event.target.value) } const handleNumberChange = (event) => { setNewNumber(event.target.value) } return ( <div> <h2> Phonebook </h2> <input type="text" placeholder="Search..." onChange= {(event) => setSearchTerm(event.target.value)} /> <h2> Add Info </h2> <form onSubmit={AddName}> <div> name: <input value={newName} onChange={handleNameChange} /> </div> <div> phonenumber: <input value={newNumber} onChange={handleNumberChange} /> </div> <div> <button type="submit"> add </button> </div> </form> <h2> Numbers </h2> <ul> {persons.filter((person) => { if (searchTerm === "") { return person } else if (person.name.toLowerCase().includes(searchTerm.toLowerCase())) { return person } }).map((person) => { return ( <li key={person.name}> {person.name} {person.number} </li> ); }) } </ul> </div> ) } export default App
AddName.js 代码
const AddName = (props, event) => { event.preventDefault() const nameObject = { name: props.newName, number: props.newNumber2 } const isNameExist = (value) => props.persons.some(person => person.name.includes(value)) if (isNameExist(nameObject.name)) { alert("name already exist") } else { props.setPersons(props.persons.concat(nameObject)) props.setNewName('') props.setNewNumber('') } } export default AddName
修复方案
核心问题是把组件当成事件处理器直接传递给onSubmit,但未正确传递props,同时AddName的参数结构错误,按以下步骤修改:
1. 修正AddName的参数与返回结构
React组件的第一个参数是props对象,事件对象不会直接作为第二个参数传入。要让它作为事件处理器,需要让AddName返回一个接收event的函数:
// 修改后的AddName.js const AddName = (props) => { return (event) => { event.preventDefault() // 修正笔误:newNumber2改为newNumber const nameObject = { name: props.newName, number: props.newNumber } // 优化判断逻辑:直接判断名称是否完全匹配 const isNameExist = props.persons.some(person => person.name === nameObject.name) if (isNameExist) { alert("name already exist") } else { // 用展开语法替代concat,更符合现代React写法 props.setPersons([...props.persons, nameObject]) props.setNewName('') props.setNewNumber('') } } } export default AddName
2. 在App.js中正确传递props并生成事件处理器
不能直接把AddName传给onSubmit,需要调用AddName并传入所有所需props,让它返回真正的事件处理函数:
// App.js中form部分修改 <form onSubmit={AddName({ persons, setPersons, newName, newNumber, setNewName, setNewNumber })}> // 原表单内容保持不变 </form>
3. 可选优化:改用标准组件模式(更符合React设计习惯)
如果想让AddName作为真正的独立组件,可以把整个表单逻辑移入AddName,彻底拆分职责:
// 优化后的AddName.js import { useState } from 'react' const AddName = ({ persons, setPersons }) => { const [newName, setNewName] = useState('') const [newNumber, setNewNumber] = useState('') const handleSubmit = (event) => { event.preventDefault() const nameObject = { name: newName, number: newNumber } const isNameExist = persons.some(person => person.name === newName) if (isNameExist) { alert("name already exist") } else { setPersons([...persons, nameObject]) setNewName('') setNewNumber('') } } return ( <form onSubmit={handleSubmit}> <div> name: <input value={newName} onChange={(e) => setNewName(e.target.value)} /> </div> <div> phonenumber: <input value={newNumber} onChange={(e) => setNewNumber(e.target.value)} /> </div> <div> <button type="submit"> add </button> </div> </form> ) } export default AddName
然后在App.js中直接引用组件:
// App.js替换原表单部分 <h2> Add Info </h2> <AddName persons={persons} setPersons={setPersons} />
这种方式彻底消除了props未使用的警告,代码结构也更清晰。
内容的提问来源于stack exchange,提问作者Jabri Juhinin
相关产品推荐
相关产品推荐

