【发布时间】:2019-03-01 16:23:19
【问题描述】:
我可以将 React.hooks 传递给一个函数并在那里使用它吗?
const [X, setX] = useState('');
function Y(useX){
useX('string');
}
Y(setX)
【问题讨论】:
标签: reactjs react-hooks
我可以将 React.hooks 传递给一个函数并在那里使用它吗?
const [X, setX] = useState('');
function Y(useX){
useX('string');
}
Y(setX)
【问题讨论】:
标签: reactjs react-hooks
使用钩子时,一定要遵守一定的hook rules(目前只有两个):
通过尝试将钩子传递给常规函数你同时违反了它们。虽然这些规则更多的是约定,而不是实际的限制,并且在某些情况下可能会起作用(正如该线程中的其他人所提到的)(您知道在哪里以及为什么可以使用它们,或者您意外满足了它们的使用要求)不建议以这种方式使用它们。例如,一段时间后您可能会忘记您的函数包含一个钩子,并且实际上取决于声明和使用它的位置和方式,然后将其移动或放入条件中,从而有效地破坏了您的应用程序的逻辑。
React 人员想出了专用的ESlint plugin 非常重要,它旨在在后台分析您的代码并在您接近违反钩子规则时准确地警告您。这是确定的方法。
如果您仍需要从组件中提取一些依赖于钩子的逻辑到单独的函数中,请考虑创建一个custom hook。
但是!
在您的示例代码中,您没有将挂钩传递给函数。 React.useState 是一个钩子,但它返回的 setX 不是。 您可以随心所欲地传递它,实际上您应该将它传递到您自定义的常规函数或自定义钩子!
在这种情况下,传递的不是钩子而是 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), []);
...
}
【讨论】:
Y 函数。
正如规则所述,钩子只能在函数组件的顶部调用,不应有条件地调用,因此虽然从技术上讲,您可以将其作为函数的参数传递,但随后您需要执行立即生效
所以
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" />
因此你不应该以这种方式使用它,因为它可能会发生你稍后在函数调用中添加一些语句,因此钩子不会保留它的调用顺序
需要维护 Hooks 调用的顺序,因为 React 依赖于 hooks 调用顺序来维护方法中使用的 hooks 队列并处理所有进一步的更新
从技术上讲,如果
useX是一个自定义钩子,它本质上是一个函数 从顶部包含钩子的组件中调用 等级
【讨论】: