繁体   English   中英

使用 react hooks 在数据 map 中使用 setState 的值动态设置 defaultChecked

[英]Dynamically set defaultChecked with value of setState within data map with react hooks

我正在尝试在从 function 返回的数据 map 的行列表中实现启用和禁用切换按钮,以从后端获取结果

问题是我需要将defaultChecked设置为 el.enabled 的任何值在json数据的el.enabled内,但没有成功

这是数据 map 的样子

data = [
    {
        "id": 1,
        "enabled": true,
    },
    {
        "id": 2,
        "enabled": false,
    },
    {
        "id": 3,
        "enabled": true,
    },
    {
        "id": 4,
        "enabled": false,
    }
]

data来自下面的 function,它从 API 后端获取值

const [data, setData] = useState([]);
    
const fetchData = async () => {
   let json = await getData();
   setData(json);
}

这是启用或禁用每一行的updateToggle function

const [statusMode, setStatusMode] = useState();

const updateToggle = async (rowID) => {
    // rowID = el.id
    const updateData = {'id': rowID}

    if ( statusMode == true ) {
      const request = await disable(updateData);
      setStatusMode(false)
    }
    
    if ( statusMode == false ) {
      const request = await enable(updateData);
      setStatusMode(true)
    }
};

这是我所拥有的,它不起作用,但显示了我正在努力实现的目标

{data.map((el, k) => {
    return (
        <div>
          <div class="checkbox">
            <label class="switch">
                <input type="checkbox" defaultChecked={setStatusMode(el.enabled, k)} onClick={() => updateToggle(el.id, k)} />
            </label>
          </div> 
        </div>
    );
  })}

问题就在这里发生defaultChecked={setStatusMode(el.enabled, k)}因为我想将值设置为我从特定行的el.enabled获得的值

目前我得到的错误是

Too many re-renders. React limits the number of renders to prevent an infinite loop.

我怎样才能做到这一点? 还是有更好的方法 go 关于这个?

问题是您正在传递并立即调用 state 更新程序 function,从而导致渲染循环。

const [statusMode, setStatusMode] = useState();

{data.map((el, k) => {
  return (
    <div>
      <div class="checkbox">
        <label class="switch">
          <input
            type="checkbox"
            defaultChecked={setStatusMode(el.enabled, k)} // <-- updates state!!
            onClick={() => updateToggle(el.id, k)}
          />
        </label>
      </div> 
    </div>
  );
})}

您应该将defaultChecked值设置为被映射的值的值。 onClick处理程序处理更新 state。

const [statusMode, setStatusMode] = useState();

{data.map((el, k) => {
  return (
    <div key={el.id}>
      <div class="checkbox">
        <label class="switch">
          <input
            type="checkbox"
            defaultChecked={el.enabled} // <-- el.enabled
            onClick={() => updateToggle(el.id, k)}
          />
        </label>
      </div> 
    </div>
  );
})}

更新

好的,我收集到你:

  1. 异步获取并存储在 state 一些“数据”。
  2. 您将此数据渲染到复选框中。
  3. 您想要切换 state调用一些端点。

代码

const [data, setData] = useState([]);

const fetchData = async () => {
  const json = await getData();
  setData(json);
};

const updateToggle = async (rowID) => {
  // rowID = el.id
  const updateData = {'id': rowID}

  // find elements first
  const dataEl = data.find(el => el.id === rowID);

  // conditionally enable/disable in backend
  if (dataEl.enabled) {
    const request = await disable(updateData);
  } else {
    const request = await enable(updateData);
  }

  // update local state
  setData(data => data.map(el => el.id === rowId
    ? { ...el, enabled: !el.enabled }
    : el
  ));
};

...

{statusMode.map((el) => {
  return (
    <div key={el.id}>
      <div class="checkbox">
        <label class="switch">
          <input
            type="checkbox"
            checked={el.enabled}
            onClick={() => updateToggle(el.id)}
          />
        </label>
      </div> 
    </div>
  );
})}

您可以将enabled的数据用作道具并将其分配给组件的初始 state

您可以在此处查看工作示例 -> https://codesandbox.io/s/clever-cookies-dn7z7?file=/src/App.js:0-873

import { useState } from "react";
import "./styles.css";

const data = [
  {
    id: 1,
    enabled: true
  },
  {
    id: 2,
    enabled: false
  },
  {
    id: 3,
    enabled: true
  },
  {
    id: 4,
    enabled: false
  }
];

export default function App() {
  return (
    <div className="App">
      {data.map((el, k) => {
        return (
          <div>
            <div class="checkbox">
              <label class="switch">
                <SingleCheckbox singleData={el} key={el.id} />
              </label>
            </div>
          </div>
        );
      })}
    </div>
  );
}

function SingleCheckbox({ singleData }) {
  const [statusMode, setStatusMode] = useState(singleData.enabled);

  return (
    <input
      type="checkbox"
      defaultChecked={statusMode}
      onClick={() => setStatusMode(!statusMode)}
    />
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM