从映射数组中单击时更改特定元素的类名,并保持相同的类名,直到在反应中再次单击

Changing classname of a specific element on click from a mapped array an keeping the same classname until clicked again in react

const allTodos = [{id: 1, name: 'whatever user type'}, { }, { }, .... { }] // Defined as an array using setState in other file. Imported in this file as allTodos using props.

export const Todos = (props) => {

const [index, setIndex] = useState(0)

props.allTodos.map((prev) => {
return (

<div id="item_container">

<button type='button' className = `check_button ${prev.id === index ? 'checked' : 'not_checked'}`
onClick = {() => setIndex(prev.id)}>

<img src = {check} alt="" id = "check_img"></img>

</button>

<li id="li_item">{prev.name}</li>
</div>

)}
}

说明:在这里,我使用 useState 设置了一个 const index,它将把它的值更改为所单击元素的 ID,以更改该元素的 className元素.

问题:现在,我成功地做到了,但每次我单击其他元素时,className 都会添加到该元素,但会从添加它的前一个元素中删除。现在我想以某种方式将 className 保留到我单击的每个元素,直到我再次单击它们以更改它们的 className。顺便说一句,我想要更改的样式是 button/element.

background

您需要能够跟踪检查的每个 索引——为此您需要一个数组(或一个用于进行位计算的数字)。有状态的 index 号码没有包含足够的信息。

const allTodos = [{ id: 1, name: 'whatever user type' }, { id: 2, name: 'foo' }];

const Todos = ({ allTodos }) => {
    const [todos, setTodos] = React.useState(() => allTodos.map(todo => ({ ...todo, checked: false })));
    const handleClick = (i) => () => {
      setTodos(todos.map((todo, j) => j !== i ? todo : ({ ...todo, checked: !todo.checked })))
    };
    return todos.map(({ id, name, checked }, i) => (
        <div id="item_container">
            <button
                type='button'
                className={`check_button ${checked ? 'checked' : 'not_checked'}`}
                onClick={handleClick(i)}
            >
                <img alt="" id="check_img"></img>
            </button>
            <div>{name}</div>
        </div >
    ))
}

ReactDOM.render(<Todos allTodos={allTodos} />, document.querySelector('.react'));
.checked {
  background-color: green;
}
.not_checked {
  background-color: yellow;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

您还需要:

  • 当不使用纯 ' " 引号时,在 prop
  • 周围使用 {} 分隔符
  • <li>s 应该只是 children 个 <ul>s
  • 重复的 ID 无效 HTML
  • 您需要 return 来自 Todos 组件的映射 JSX
  • 您在 allTodos.map
  • 末尾缺少一个 )

您应该使用数组来保存点击并在再次点击时从数组中删除 id。

const [idList, setIdList] = useState([])

const handleClick=(id, checked) => {
  if(checked){
    setIdList.filter(item => item !== id)
  } else {
    setIdList([...idList, id])
  }
}

props.allTodos.map((prev) => {
   const checked = idList.includes(prev.id)
   ...  
   className ={`check_button ${checked ? 'checked' : 'not_checked'}`}
   onClick = {() => handleClick(prev.id, checked)
   ...