如何在列表中以不同方式定位每个元素?
How can I target each element differently in list?
我想以不同的方式操作每个“li”。就像有 3 个“li”,所以当我点击它相应的按钮时,只有那个应该改变,但所有三个都在改变(我能理解为什么会这样)但是有什么办法可以找到解决方案所以只有相应的列表在div中
更改
const nextThree =[];
for(let i=3;i<6;i++){
nextThree.push(<div className="week-item">
<h1>{weeks?.[i].weekday}</h1>
<ul>
{weeks?.[i].tasks.map(task =>{
return(
<li onClick={()=> setDone(true)} className={done?"b":""}><button></button>{task}</li>
);
})}
</ul>
</div>);
}
注意:我有一个包含 6 个元素的数组,它们 div 分为两个 div,每个 div 包含 3 个元素,这就是为什么我使用这样的循环
要设置元素的状态(例如 done
),您需要跟踪状态。在带有功能组件的 React 中,您可以使用 useState
挂钩。
const { useState } = React
const Weekday = ({ weekday = '', tasks = [], handleClick }) => {
return (
<div>
<h2>{weekday}</h2>
<ul>
{
tasks.map(({ name = '', done = false }, idx) => {
return (
<li
key={idx}
className={`task ${done ? 'done' : ''}`}
onClick={() => handleClick(name)}
>{name}</li>
)
})
}
</ul>
</div>
)
}
const App = ({ weekly }) => {
// for tracking state of tasks
const [state, setState] = useState(weekly)
const setDone = (weekday) => (taskName) => {
// setting new state based on weekday & taskName
// parameters; merging with unchanged data
setState(prevState => {
return prevState.map(day => {
if (day.weekday !== weekday) {
return day
} else {
return {
...day,
tasks: day.tasks.map(task => {
if (task.name !== taskName) {
return task
} else {
return {
...task,
done: !task.done,
}
}
})
}
}
})
})
}
return (
<div>
{
state.map(({ weekday, tasks }, idx) => {
return (
<Weekday
key={idx}
weekday={weekday}
tasks={tasks}
handleClick={setDone(weekday)}
/>
)
})
}
</div>
)
}
const data = [
{
weekday: 'Monday',
tasks: [
{
name: 'Monday task 1',
done: false,
},
{
name: 'Monday task 2',
done: false,
},
{
name: 'Monday task 3',
done: false,
},
]
},
{
weekday: 'Tuesday',
tasks: [
{
name: 'Tuesday task 1',
done: false,
},
{
name: 'Tuesday task 2',
done: false,
},
{
name: 'Tuesday task 3',
done: false,
},
]
},
{
weekday: 'Wednesday',
tasks: [
{
name: 'Wednesday task 1',
done: false,
},
{
name: 'Wednesday task 2',
done: false,
},
{
name: 'Wednesday task 3',
done: false,
},
]
},
]
ReactDOM.render(
<App weekly={data} />,
document.getElementById('root')
);
.task {
cursor: pointer;
}
.done {
text-decoration: line-through;
}
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>
处理这些组件的状态可能有不同的解决方案 - 可能将任务状态下推到 Weekday
组件会使更新功能更简单。在这种情况下,唯一有状态的组件是 App
:这样更容易更改 Weekday
组件,因为您只需要关心它接收到的道具。
我想以不同的方式操作每个“li”。就像有 3 个“li”,所以当我点击它相应的按钮时,只有那个应该改变,但所有三个都在改变(我能理解为什么会这样)但是有什么办法可以找到解决方案所以只有相应的列表在div中
更改 const nextThree =[];
for(let i=3;i<6;i++){
nextThree.push(<div className="week-item">
<h1>{weeks?.[i].weekday}</h1>
<ul>
{weeks?.[i].tasks.map(task =>{
return(
<li onClick={()=> setDone(true)} className={done?"b":""}><button></button>{task}</li>
);
})}
</ul>
</div>);
}
注意:我有一个包含 6 个元素的数组,它们 div 分为两个 div,每个 div 包含 3 个元素,这就是为什么我使用这样的循环
要设置元素的状态(例如 done
),您需要跟踪状态。在带有功能组件的 React 中,您可以使用 useState
挂钩。
const { useState } = React
const Weekday = ({ weekday = '', tasks = [], handleClick }) => {
return (
<div>
<h2>{weekday}</h2>
<ul>
{
tasks.map(({ name = '', done = false }, idx) => {
return (
<li
key={idx}
className={`task ${done ? 'done' : ''}`}
onClick={() => handleClick(name)}
>{name}</li>
)
})
}
</ul>
</div>
)
}
const App = ({ weekly }) => {
// for tracking state of tasks
const [state, setState] = useState(weekly)
const setDone = (weekday) => (taskName) => {
// setting new state based on weekday & taskName
// parameters; merging with unchanged data
setState(prevState => {
return prevState.map(day => {
if (day.weekday !== weekday) {
return day
} else {
return {
...day,
tasks: day.tasks.map(task => {
if (task.name !== taskName) {
return task
} else {
return {
...task,
done: !task.done,
}
}
})
}
}
})
})
}
return (
<div>
{
state.map(({ weekday, tasks }, idx) => {
return (
<Weekday
key={idx}
weekday={weekday}
tasks={tasks}
handleClick={setDone(weekday)}
/>
)
})
}
</div>
)
}
const data = [
{
weekday: 'Monday',
tasks: [
{
name: 'Monday task 1',
done: false,
},
{
name: 'Monday task 2',
done: false,
},
{
name: 'Monday task 3',
done: false,
},
]
},
{
weekday: 'Tuesday',
tasks: [
{
name: 'Tuesday task 1',
done: false,
},
{
name: 'Tuesday task 2',
done: false,
},
{
name: 'Tuesday task 3',
done: false,
},
]
},
{
weekday: 'Wednesday',
tasks: [
{
name: 'Wednesday task 1',
done: false,
},
{
name: 'Wednesday task 2',
done: false,
},
{
name: 'Wednesday task 3',
done: false,
},
]
},
]
ReactDOM.render(
<App weekly={data} />,
document.getElementById('root')
);
.task {
cursor: pointer;
}
.done {
text-decoration: line-through;
}
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>
处理这些组件的状态可能有不同的解决方案 - 可能将任务状态下推到 Weekday
组件会使更新功能更简单。在这种情况下,唯一有状态的组件是 App
:这样更容易更改 Weekday
组件,因为您只需要关心它接收到的道具。