reactjs 点击按钮后,我希望该特定的div触发事件

qzwqbdag  于 2023-06-22  发布在  React
关注(0)|答案(2)|浏览(126)

一个Todo App每当我点击check时,它应该只为Div的特定元素(Array Elements)触发handleCheck()

在所有div(Array Elements)中触发handleCheck()。

const todoData = [
        
        {id:0,todoname:"Study",todotoday:"Completing CSS today"},
        {id:1,todoname:"Coding",todotoday:"Leetcode 2 Problems"}
    ];

    const [myArray,setmyArray] = useState(todoData);
    const [isChecked, setIsChecked] = useState();

 const handleCheck = (id) =>{
        console.log(id);
      setIsChecked(current => !current);
    }
 return (
 <div className="todomain">
    {
 myArray.map((obj)=>{
          return ( <div className="todobox" key={obj.id} style={{opacity:isChecked ? 0 : ''}}>
          <div className="checkcont">
           <img src={check} alt="Check" className='chkbtn btn' onClick={() => handleCheck(obj.id)}/>
          </div>
            <h2 className="head" >Todo: {obj.todoname}</h2>
            <h3 className="todocont">{obj.todotoday}</h3>
            <div className="todoboxbtn">
             <TodoIcon />
            </div>
            </div> )
        })
      }
</div>
   )
5us2dqdw

5us2dqdw1#

因为“一件事”和“很多事”是有区别的。
这个状态代表了很多东西(数组):

const [myArray,setmyArray] = useState(todoData);

但是这个状态代表一件事(一个单一的值):

const [isChecked, setIsChecked] = useState();

那么,当isCheckedtrue时,它适用于myArray的哪个元素?目前,您的选项是“全部”或“没有”。
也许你想存储id值,而不是只存储一个布尔值?例如:

const [checkedItem, setCheckedItem] = useState();

const handleCheck = (id) =>{
  console.log(id);
  setCheckedItem(id);
}

那么checkedItem将包含当前选中的一个“项”的id。然后比较代码中的id,以有条件地设置元素样式:

<div
  className="todobox"
  key={obj.id}
  style={{ opacity: (checkedItem === obj.id) ? 0 : '' }}
>

或者,如果您想将“检查项”作为“许多事物”来跟踪,那么这将是一个数组。例如:

const [checkedItems, setCheckedItems] = useState([]);

检查/取消检查项将是在该数组中添加/删除项的问题。例如:

const handleCheck = (id) =>{
  console.log(id);
  if (checkedItems.includes(id)) {
    setCheckedItems(checkedItems.filter(i => i !== id));
  } else {
    setCheckedItems([...checkedItems, id]);
  }
}

JSX标记中的条件是检查数组 * 是否包含 * obj.id值(而不是 * 是 * obj.id值)。例如:

<div
  className="todobox"
  key={obj.id}
  style={{ opacity: checkedItems.includes(obj.id) ? 0 : '' }}
>
eufgjt7s

eufgjt7s2#

为了使这段代码正常工作,你应该将isChecked属性添加到你的数据中,并修改你更新状态的方式。
你的最终代码看起来像这样:

const todoData = [
    {
      id: 0,
      todoname: 'Study',
      todotoday: 'Completing CSS today',
      isChecked: false, // new boolean property
    },
    {
      id: 1,
      todoname: 'Coding',
      todotoday: 'Leetcode 2 Problems',
      isChecked: false, // new boolean property
    },
  ]

  const [myArray, setMyArray] = useState(todoData)

  /**
   * Given obj id, map all items inside MyArray. If obj.id was found, update it's
   * isChecked property. Finally use setMyArray to update the state and re-render UI
   * @param {Number} id the id of a certain obj in MyArray
   */
  const toggleTodoCheck = (id) => {
    const updatedMyArray = myArray.map((obj) => {
      if (obj.id === id) return { ...obj, isChecked: !obj.isChecked }
      return obj
    })
    setMyArray(updatedMyArray)
  }
  return (
    <div className="todomain">
      {myArray.map((obj) => {
        return (
          <div
            className="todobox"
            key={obj.id}
            style={{ opacity: obj.isChecked ? 0 : '' }}
          >
            <div className="checkcont">
              <img
                src={check}
                alt="Check"
                className="chkbtn btn"
                onClick={() => toggleTodoCheck(obj.id)}
              />
            </div>
            <h2 className="head">Todo: {obj.todoname}</h2>
            <h3 className="todocont">{obj.todotoday}</h3>
            <div className="todoboxbtn">
              <TodoIcon />
            </div>
          </div>
        )
      })}
    </div>
  )

相关问题