我可以将react.hooks传递给函数并在那里使用吗?
const [X, setX] = useState('');
function Y(useX){
useX('string');
}
Y(setX)
使用钩子时,您必须遵守某些钩规则(目前只有两个规则):
- 仅在顶级呼叫钩
- 仅来自React功能的钩钩
通过尝试将钩子传递给常规功能您违反了它们。尽管这些规则比实际的限制更多,但在某些情况下可能会起作用()不小心满足其使用要求)不建议以这种方式使用它们。例如,一段时间后,您可能会忘记您的功能包含一个钩子,而实际上取决于声明和使用的何处,将其移动,或者将其移动或放入有条件的,有效地打破了您的应用程序的逻辑。
非常重要的是,React人们提出了专用的ESLINT插件,该插件旨在在后台分析您的代码并在接近违反挂钩规则的情况下确切警告您。这是确定的方法。
如果您仍然需要从组件中提取一些挂钩逻辑到单独的函数,请考虑创建自定义钩。
但是!
在您的示例代码中,您没有将挂钩传递给函数。React.useState
是一个钩子,但返回的setX
不是。您可以将其传递,但实际上可以将其传递给您的自定义定期功能或自定义挂钩!
作为规则所述,钩子只能在功能组件的顶部调用,不应有条件地调用钩子,因此,虽然从技术上讲,您可以将其作为函数的参数传递,但但是然后您需要立即执行该函数
so
const App = () => {
const [X, setX] = React.useState('x');
function Y(useX){
useX('string');
}
Y(React.useState);
return <div>Hello {X}</div>
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app" />
可以。
但下面的代码无法正常工作
const App = () => {
const [X, setX] = React.useState('x');
function Y(useX){
useX('string');
}
return <div>Hello {X} <button onClick={() => {Y(React.useState)}}>Click</button></div>
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app" />
因此,您不应该以这种方式使用它,因为它可能会这样,以便您以后在函数调用中添加一些语句,因此挂钩无法保留其呼叫的顺序
需要维护挂钩调用顺序,因为反应依赖于挂钩呼叫顺序来维持方法中使用的钩子队列,并处理所有其他更新
从技术上讲,如果
useX
是自定义钩,它本质上是一个功能 从在顶部包含钩子的组件中调用 等级
在这种情况下,它不是钩子,而是传递的setter函数,挂钩限制不适用于Y(setX)
。它不一定驻留在组件范围:
function Y(setX){
setX('string');
}
const Comp = () => {
const [X, setX] = useState('');
Y(setX);
...
}
取决于用法可能会受益于记忆,例如,如果应通过() => Y(setX)
作为道具传递:
const Comp = () => {
const [X, setX] = useState('');
const setY = useCallback(() => Y(setX), []);
...
}