我正在制作一个todo列表,在下面的Tasks
组件中,我有一个带有映射数据的li
组件。我想有条件地在我使用初始属性为null
的useState
挂钩的任务上添加删除线。
然后,我添加了onClick
函数,将状态分别更改为true
和false
,但我的风格没有被应用:(
以下是相同的代码
import React, {useState} from 'react';
import "./Tasks.css";
import DoneIcon from '@mui/icons-material/Done';
import CloseIcon from '@mui/icons-material/Close';
function Tasks(props) {
const [done, setDone] = useState(null);
return (
<div className="tasks">
{props.items.map(item => (
<li key={item.id} onClick={() => setDone(false)} style={{textDecorationLine: done && 'line-through'}}>{item.text}
<div>
<button onClick={() => setDone(true)} style={{color: "green"}}><DoneIcon/></button>
<button style={{color: "red"}}><CloseIcon/></button>
</div>
</li>
))}
</div>
)
}
export default Tasks;
您的代码有几个问题:
- 如果要保存每个任务的状态,则不能使用单个布尔值。您需要一个数组或对象,每个任务包含一个值
- 单击"完成"按钮时,会触发两个
onClick
回调(一个用于<button>
,另一个用于<li>
(,将done
的值设置为true
,然后立即再次设置为false
要求解[1],可以将done
变量设置为对象,其中每个键都是一个项id,匹配值是一个布尔值,用于确定任务是否完成。
要解决[2],请从<li>
中删除onClick
。如果在按钮的onClick
中基于以前的状态设置任务状态,则仍然可以实现切换效果。
以下代码应该是您需要的:
// done is an object that maps task ids to booleans
const [done, setDone] = useState({});
return (
<div className="tasks">
{props.items.map(item => (
<li key={item.id} style={{textDecorationLine: done[item.id] && 'line-through'}}>{item.text}
<div>
<button onClick={() => setDone(prevState => ({...prevState, [item.id]: !prevState[item.id]}))} style={{color: "green"}}><DoneIcon/></button>
<button style={{color: "red"}}><CloseIcon/></button>
</div>
</li>
))}
</div>
)
您需要保存item.id
来确定单击了哪个项目,而不是布尔值。
import React, {useState} from 'react';
import "./Tasks.css";
import DoneIcon from '@mui/icons-material/Done';
import CloseIcon from '@mui/icons-material/Close';
function Tasks(props) {
const [taskWasDone, setTaskWasDone] = useState(null);
return (
<div className="tasks">
{props.items.map(item => (
<li key={item.id} onClick={() => setTaskWasDone(null)} style={{textDecorationLine: taskWasDone === item.id && 'line-through'}}>{item.text}
<div>
<button onClick={() => setTaskWasDone(item.id)} style={{color: "green"}}><DoneIcon/></button>
<button style={{color: "red"}}><CloseIcon/></button>
</div>
</li>
))}
</div>
)
}
export default Tasks;