【问题标题】:Changing classname of a specific element on click from a mapped array an keeping the same classname until clicked again in react从映射数组中单击更改特定元素的类名并保持相同的类名直到再次单击反应
【发布时间】:2021-11-02 10:00:28
【问题描述】:
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 设置了一个常量index,它将其值更改为单击的元素的ID,以更改该元素的className

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

【问题讨论】:

    标签: reactjs react-functional-component


    【解决方案1】:

    您需要能够跟踪检查的每个索引 - 为此,您需要一个数组(或用于进行位计算的数字)。有状态的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>

    你还需要:

    • 如果不使用纯 ' " 引号,请在属性周围使用 {} 分隔符
    • &lt;li&gt;s 只能是 &lt;ul&gt;s 的子级
    • 重复的 ID 是无效的 HTML
    • 你需要从Todos组件返回映射的JSX
    • 您在allTodos.map 末尾缺少)

    【讨论】:

    • 我可以知道这里是否使用“j”作为参数吗?如果是,那么它作为参数得到了什么?
    • 是的,.map 回调的第二个参数是被迭代的索引。第一次迭代为 0,第二次迭代为 1,以此类推。用于确定 todos 数组中更改的索引。
    【解决方案2】:

    您应该使用数组来保存单击的 id,并在再次单击时从数组中删除 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)
       ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 2011-08-08
      • 1970-01-01
      • 2010-12-21
      相关资源
      最近更新 更多