我如何定位被点击的 React 组件
Posted
技术标签:
【中文标题】我如何定位被点击的 React 组件【英文标题】:How do i target React component which is clicked 【发布时间】:2021-05-17 14:22:31 【问题描述】:我想在单击时更改组件的类。我使用状态创建一个具有 name 和 done 属性的新组件(创建时为 false)。然后将其推送到 todos 数组中。 现在的问题是如何找到单击了哪个组件并将其“完成”属性更改为 !done ?
function App()
const [todos, setTodos] = useState([])
const [newTodo, setNewTodo] = useState(
name: "",
done: false
)
const handleInput = (event) =>
setNewTodo(name: event.target.value)
const handleDone = (event) =>
//WHAT TO DO HERE
const submitTodo = (event) =>
event.preventDefault();
setTodos([...todos, newTodo.name])
console.log(newTodo.name)
setNewTodo(name: "")
return (
<div className="App">
<form onSubmit=submitTodo>
<input onChange=handleInput value=newTodo.name/>
<button>Add Todo!</button>
</form>
<ul>
todos.map(todo => (
<li className=/*Change the class based on the DONE property*/ onClick=handleDone>todo</li>
))
</ul>
</div>
);
export default App;
【问题讨论】:
我认为你应该使用 onClick=() => handleDone(todo) 然后 todo 应该在你的handleDone方法的事件参数中(但不确定,因为我没有做过任何反应了很长一段时间) 【参考方案1】:首先,您应该始终让您的待办事项同时包含name
和done
属性。有了这个,您只需将待办事项从点击的<li>
传递给您的点击处理程序,这样它就可以修改其完成属性并通过更新todos
状态来重新渲染。
function App()
const [todos, setTodos] = useState([])
const [newTodo, setNewTodo] = useState(
name: "",
done: false
)
const handleInput = (event) =>
setNewTodo(name: event.target.value, done: false ); // this now adds done property
const handleDone = (todo) =>
todo.done = !todo.done;
setTodos([...todos]); // This sets new todos to cause a rerender with updated list
const submitTodo = (event) =>
event.preventDefault();
setTodos([...todos, newTodo]) // this now appends entire newTodo item not only it's name
setNewTodo(name: "", done: false) // this now also sets default done
return (
<div className="App">
<form onSubmit=submitTodo>
<input onChange=handleInput value=newTodo.name/>
<button>Add Todo!</button>
</form>
<ul>
todos.map(todo => (
<li
className=todo.done ? 'classA' : 'classB'
onClick=() => handleDone(todo)
>
todo.name // this now displays todo.name not todo
</li>
))
</ul>
</div>
);
export default App;
此外,您可以将待办事项和点击处理程序提取到单独的组件中:
function ToDo( item )
const [clicked, setClicked] = useState(item.done);
const handleClick = useCallback(() =>
item.done = !clicked
setClicked(!clicked);
, [clicked]);
return <li
className=clicked ? 'classA' : 'classB'
onClick=handleClick
>
item.name
</li>;
然后用你的 App 组件渲染一个组件列表:
<ul>
todos.map(todo => <ToDo item=todo />
</ul>
【讨论】:
这解决了它。是的,我创建了“完成”属性,但我的 todos 在推送到 todos 或函数中时不包含它。谢谢。【参考方案2】:改变你的 newTodo 状态
const [newTodo, setNewTodo] = useState('');
const [show,setShow] = useState(false);
const handleDone = (event) => setShow(!show)
.....
.....
.....
<li className=show ? 'classname when show is true': 'classname when show is false' onClick=handleDone>todo</li>
【讨论】:
简单,但它仍然不针对特定的待办事项。单击一个后,所有类别都会更改。但仍然感谢您的贡献。以上是关于我如何定位被点击的 React 组件的主要内容,如果未能解决你的问题,请参考以下文章
React-bootstrap NavBar 和组件定位使用 css 问题