当点击按钮时,我希望特定的div触发事件。

huangapple go评论72阅读模式
英文:

Upon Click on button i want that particular div to trigger event

问题

有一个待办事项应用程序。
每当我点击复选框时,它应该只触发Div数组元素的handleCheck()函数。

它在所有的Div数组元素中触发了handleCheck()。

 const todoData = [
        
        {id:0,todoname:"学习",todotoday:"今天完成CSS"},
        {id:1,todoname:"编程",todotoday:"Leetcode解决2个问题"}
    ];

    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" >待办事项{obj.todoname}</h2>
            <h3 className="todocont">{obj.todotoday}</h3>
            <div className="todoboxbtn">
             <TodoIcon />
            </div>
            </div> )
        })
      }
</div>
   )
英文:

Have a Todo App.
Whenever i will click on check it should only trigger handleCheck() for that particular element of Div(Array Elements)

It is triggering handleCheck() in all the div(Array Elements).

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

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

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

答案1

得分: 1

为了使这段代码正常工作,你应该在你的数据中添加一个 isChecked 属性,并修改更新状态的方式。

你的最终代码将如下所示:

  const todoData = [
    {
      id: 0,
      todoname: '学习',
      todotoday: '今天完成 CSS',
      isChecked: false, // 新的布尔属性
    },
    {
      id: 1,
      todoname: '编码',
      todotoday: 'Leetcode 解决 2 个问题',
      isChecked: false, // 新的布尔属性
    },
  ]

  const [myArray, setMyArray] = useState(todoData)

  /**
   * 给定对象的 id,映射 MyArray 中的所有项目。如果找到 obj.id,则更新其 isChecked 属性。
   * 最后使用 setMyArray 更新状态并重新渲染 UI。
   * @param {Number} id MyArray 中某个对象的 id
   */
  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">待办事项{obj.todoname}</h2>
            <h3 className="todocont">{obj.todotoday}</h3>
            <div className="todoboxbtn">
              <TodoIcon />
            </div>
          </div>
        )
      })}
    </div>
  )
英文:

In order to make this code work properly you should add isChecked property to your data and modify the way you update your state.

You final code will look like this:

  const todoData = [
    {
      id: 0,
      todoname: &#39;Study&#39;,
      todotoday: &#39;Completing CSS today&#39;,
      isChecked: false, // new boolean property
    },
    {
      id: 1,
      todoname: &#39;Coding&#39;,
      todotoday: &#39;Leetcode 2 Problems&#39;,
      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&#39;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) =&gt; {
    const updatedMyArray = myArray.map((obj) =&gt; {
      if (obj.id === id) return { ...obj, isChecked: !obj.isChecked }
      return obj
    })
    setMyArray(updatedMyArray)
  }
  return (
    &lt;div className=&quot;todomain&quot;&gt;
      {myArray.map((obj) =&gt; {
        return (
          &lt;div
            className=&quot;todobox&quot;
            key={obj.id}
            style={{ opacity: obj.isChecked ? 0 : &#39;&#39; }}
          &gt;
            &lt;div className=&quot;checkcont&quot;&gt;
              &lt;img
                src={check}
                alt=&quot;Check&quot;
                className=&quot;chkbtn btn&quot;
                onClick={() =&gt; toggleTodoCheck(obj.id)}
              /&gt;
            &lt;/div&gt;
            &lt;h2 className=&quot;head&quot;&gt;Todo: {obj.todoname}&lt;/h2&gt;
            &lt;h3 className=&quot;todocont&quot;&gt;{obj.todotoday}&lt;/h3&gt;
            &lt;div className=&quot;todoboxbtn&quot;&gt;
              &lt;TodoIcon /&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        )
      })}
    &lt;/div&gt;
  )

答案2

得分: 0

因为 "一件事" 和 "许多事情" 之间存在差异。

这个状态表示许多事情(一个数组):

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 : '' }}
>
英文:

Because there's a difference between "one thing" and "many things".

This state represents many things (an array):

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

But this state represents one thing (a single value):

const [isChecked, setIsChecked] = useState();

So, when isChecked is true, which element of myArray does it apply to? Currently your options are "all of them" or "none of them".

Instead of just storing a boolean value, perhaps you meant to store the id value? For example:

const [checkedItem, setCheckedItem] = useState();
const handleCheck = (id) =&gt;{
console.log(id);
setCheckedItem(id);
}

Then checkedItem would contain the id of the one "item" which is currently checked. You'd then compare that id in the code to conditionally style your elements:

&lt;div
className=&quot;todobox&quot;
key={obj.id}
style={{ opacity: (checkedItem === obj.id) ? 0 : &#39;&#39; }}
&gt;

Alternatively, if you want to track "checked items" as "many things" then that would be an array. For example:

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

Checking/unchecking items would be a matter of adding/removing items in that array. For example:

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

And the condition in the JSX markup would be checking if that array contains the obj.id value (rather than is the obj.id value). For example:

&lt;div
className=&quot;todobox&quot;
key={obj.id}
style={{ opacity: checkedItems.includes(obj.id) ? 0 : &#39;&#39; }}
&gt;

huangapple
  • 本文由 发表于 2023年6月22日 03:07:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526405.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定