[英]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>
);
})}
好的,我收集到你:
代码
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.