我有一堆復選框組件,我想在每次切換復選框組件時更新父組件的狀態。現在我正在這樣做:
const selChangeHandler = useCallback(
(checkboxId, isSel) => {
if (isSel) setSelectedCheckboxes((prevState) => [...prevState, checkboxId]);
else
setSelectedCheckboxes((prevState) =>
prevState.filter((x) => x != checkboxId)
);
},
[setSelectedCheckboxes]
);
這個函式被傳遞到每個復選框中。我不認為這是一個特別好的方法,因為每個復選框都可以向陣列添加任何內容,而不僅僅是它的 id。所以我嘗試了這個,但我得到了一個錯誤:
const GetSelChangeHandler = (checkboxId) => {
return useCallback(
(isSel) => {
if (isSel) setSelectedCheckboxes((prevState) => [...prevState, checkboxId]);
else
setSelectedCheckboxes((prevState) =>
prevState.filter(
(x) => x != checkboxId
)
);
},
[setSelectedCheckboxes]
); };
我執行這個行內并將回傳的處理程式作為回呼道具傳遞給我的復選框組件。我不確定錯誤是什么,但與違反鉤子規則有關。這樣做的正確方法是什么?
uj5u.com熱心網友回復:
鉤子規則
不要在回圈、條件或嵌套函式中呼叫 Hook。相反,在任何提前回傳之前,始終在 React 函式的頂層使用 Hooks。
你不應該使用useCallback()inside GetSelChangeHandler,以防你有條件地呼叫它。
const GetSelChangeHandler = (checkboxId) => {
return (isSel) => {
if (isSel) setSelectedCheckboxes((prevState) => [...prevState, checkboxId]);
else
setSelectedCheckboxes((prevState) => prevState.filter(x => x !=checkboxId));
};
};
uj5u.com熱心網友回復:
您不能在回圈或條件中呼叫鉤子。像useToggle自定義鉤子這樣可以更輕松地管理許多復選框的狀態的東西怎么樣?Run下面的代碼,點擊一些?,看看應用程式狀態如何反映變化。
function useToggle(initState = false) {
const [state, setState] = React.useState(initState)
return [state, _ => setState(!state)]
}
function App() {
const [inStock, toggleInStock] = useToggle(true)
const [freeShip, toggleFreeShip] = useToggle(true)
const [onSale, toggleOnSale] = useToggle(true)
return <div>
In Stock: <Checkbox checked={inStock} onClick={toggleInStock} /><br/>
Free Shipping: <Checkbox checked={freeShip} onClick={toggleFreeShip} /><br/>
On Sale: <Checkbox checked={onSale} onClick={toggleOnSale} on="??" /><br/>
<pre>{JSON.stringify({ inStock, freeShip, onSale })}</pre>
</div>
}
function Checkbox({ checked, onClick, on = "?", off = "?" }) {
// use <input type="checkbox"> or any custom representation
return <div className="checkbox" onClick={onClick}>
{checked ? on : off}
</div>
}
ReactDOM.render(<App/>, document.querySelector("#app"))
.checkbox { display: inline-block; cursor: pointer; }
pre { background-color: #ff8; padding: 0.5rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
如果復選框的數量未知,則可以使用useToggles變體來解決問題。
function useToggles(init = {}) {
const [states, setStates] = React.useState(init)
return [
states,
key => event => setStates({...states, [key]: !Boolean(states[key])})
]
}
function App() {
const [checkboxes, toggle] = useToggles({
inStock: true,
freeShip: true,
onSale: true
})
return <div>
In Stock:
<Checkbox checked={checkboxes.inStock} onClick={toggle("inStock")}/><br/>
Free Shipping:
<Checkbox checked={checkboxes.freeShip} onClick={toggle("freeShip")}/><br/>
On Sale:
<Checkbox checked={checkboxes.onSale} onClick={toggle("onSale")} on="??"/><br/>
<pre>{JSON.stringify(checkboxes)}</pre>
</div>
}
function Checkbox({ checked, onClick, on = "?", off = "?" }) {
// use <input type="checkbox"> or any custom representation
return <div className="checkbox" onClick={onClick}>
{checked ? on : off}
</div>
}
ReactDOM.render(<App/>, document.querySelector("#app"))
.checkbox { display: inline-block; cursor: pointer; }
pre { background-color: #ff8; padding: 0.5rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/432998.html
標籤:javascript 反应 设计模式 反应钩子 使用回调
上一篇:如何使用refs測驗反應組件?
