【问题标题】:how to implement checkbox in react (checked and unchecked functionality)?如何在反应中实现复选框(选中和未选中的功能)?
【发布时间】:2020-12-13 14:31:48
【问题描述】:

我正在尝试在反应中实现复选框,但在选中和取消选中复选框时遇到问题。

我尝试实现onchange处理程序。

onChange={() => {
                    // first approch
                    //  i.checked = !i.checked;
                    // setObj({ ...i});

                    // second approach
                    setObj({ ...i, checked: !i.checked });
                    setTimeout(ab, 2000);
                  }}

所以我用了两种方法

在第一种方法中,我更改了toggle the checked 属性,然后创建了新的reference 工作正常

 i.checked = !i.checked;
   setObj({ ...i});

在第二种方法中,我使用toggle of checked property 创建了一个新对象或引用但这不起作用,原因

{ ...i, checked: !i.checked }

为什么我的第一种和第二种方法不同?

这是我的代码

https://codesandbox.io/s/lucid-fire-cxp9c?file=/src/child.js:362-666

import React from "react";
export default function Child({ data, ab }) {
  const [obj, setObj] = React.useState(null);

  return (
    <>
      {data &&
        data.map((i, idx) => {
          return (
            <ul key={idx}>
              <li>
                <input
                  type="checkbox"
                  checked={i.checked}
                  onChange={() => {
                    // first approch
                    //  i.checked = !i.checked;
                    // setObj({ ...i});

                    // second approach
                    setObj({ ...i, checked: !i.checked });
                    setTimeout(ab, 2000);
                  }}
                />
                {i.label}
              </li>
              {i.childrens && i.childrens.length > 0 ? (
                <Child data={i.childrens} ab={ab} />
              ) : null}
            </ul>
          );
        })}
    </>
  );
}

有什么建议...!!?

【问题讨论】:

    标签: javascript reactjs redux react-redux


    【解决方案1】:

    好的,所以混合 state 和 props 会有点混乱。我做了一些重构,并为您正在使用的嵌套值树添加了一点递归。我在所做的更改之上添加了 cmets。

    var data = [/* your array of data */]
    
    
    // recursive function to find the value in the tree
    const setChecked = (data, label) => {
      if (!data || data.length === 0) return [];
      // grab the first element
      const [current, ...rest] = data;
    
      // if it's found, plop the element back into place with
      // check changed and dump in the rest of the elements
      if (current.label === label) {
        return [
          {
            ...current,
            checked: !current.checked,
            childrens: current.childrens.map((child) => ({
              ...child,
              checked: !current.checked
            }))
          },
          ...rest
        ];
      }
    
      // re-slot the element and recursively move
      // through the remaining siblings
      return [
        {
          ...current,
          childrens:
            current.childrens.length > 0
              ? setChecked(current.childrens, label)
              : current.childrens
        },
        ...setChecked(rest, label)
      ];
    };
    
    export default function App() {
      const [state, setState] = React.useState(data1);
    
      const handleChange = (data) => {
        setState(setChecked(state, data.label));
      };
    
      const ab = () => {
        console.log(JSON.stringify(state));
      };
    
      return (
        <div className="App">
          <Child data={state} ab={ab} handleChange={handleChange} />
        </div>
      );
    }
    
    // added the onChange handler to lift the state to the parent
    export default function Child({ data, ab, onChange }) {
      return (
        <>
          {data &&
            data.map((i, idx) => {
              return (
                <ul key={idx}>
                  <li>
                    <input
                      type="checkbox"
                      checked={i.checked}
                      onChange={() => {
                        onChange(i);
                        setTimeout(ab, 2000);
                      }}
                    />
                    {i.label}
                  </li>
                  {i.childrens && i.childrens.length > 0 ? (
                    <Child data={i.childrens} ab={ab} onChange={onChange} />
                  ) : null}
                </ul>
              );
            })}
        </>
      );
    }
    

    【讨论】:

    • 我完全同意你的观点。但是每个高级开发人员都说让可重用组件正确吗?和事件处理程序应该在同一个组件中......如果我们将处理程序移动到父组件。那么父组件与子组件的依赖关系
    • 还有更好的设计吗?
    • in setChecked 函数你没有检查父级childrens object..它只是检查one level
    • 最后一个问题,如果有人向您提出了这个问题。您将选择parent child 的方法(形成孩子,您将点击处理程序发送给父母)。或者你创建单独的组件reusable component 也有点击处理程序
    • @sorry 实际上我是 react 的初学者,所以我问什么是更好的方法
    猜你喜欢
    • 1970-01-01
    • 2020-04-07
    • 2020-10-19
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 2018-06-05
    相关资源
    最近更新 更多