[英]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.