React.Js - 回调生成器中的 useCallback
React.Js - useCallback inside a callback generator
我有一堆复选框组件,我想在每次切换复选框组件时更新父组件的状态。现在我正在这样做:
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]
); };
我执行此内联并将返回的处理程序作为回调道具传递给我的复选框组件。我不确定错误是什么,但与违反钩子规则有关。这样做的正确方法是什么?
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns.
你不应该在 GetSelChangeHandler
中使用 useCallback()
,以防你有条件地调用它。
const GetSelChangeHandler = (checkboxId) => {
return (isSel) => {
if (isSel) setSelectedCheckboxes((prevState) => [...prevState, checkboxId]);
else
setSelectedCheckboxes((prevState) => prevState.filter(x => x !=checkboxId));
};
};
您不能在循环或条件中调用挂钩。像 useToggle
自定义挂钩这样的东西怎么样,它可以更轻松地管理许多复选框的状态? 运行下面的代码,点击一些✅
,看看应用状态如何反映变化。
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>
我有一堆复选框组件,我想在每次切换复选框组件时更新父组件的状态。现在我正在这样做:
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]
); };
我执行此内联并将返回的处理程序作为回调道具传递给我的复选框组件。我不确定错误是什么,但与违反钩子规则有关。这样做的正确方法是什么?
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns.
你不应该在 GetSelChangeHandler
中使用 useCallback()
,以防你有条件地调用它。
const GetSelChangeHandler = (checkboxId) => {
return (isSel) => {
if (isSel) setSelectedCheckboxes((prevState) => [...prevState, checkboxId]);
else
setSelectedCheckboxes((prevState) => prevState.filter(x => x !=checkboxId));
};
};
您不能在循环或条件中调用挂钩。像 useToggle
自定义挂钩这样的东西怎么样,它可以更轻松地管理许多复选框的状态? 运行下面的代码,点击一些✅
,看看应用状态如何反映变化。
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>