是否可以将React.hook传递给函数?

问题描述 投票:1回答:3

我可以将React.hooks传递给函数并在那里使用吗?

    const [X, setX] = useState('');

    function  Y(useX){
       useX('string');
    }
    Y(setX)
reactjs react-hooks
3个回答
5
投票

使用钩子时,你必须遵守某些hook rules(目前只有两个):

  1. 只有最高级别的呼叫挂钩
  2. 只有来自React Functions的Call Hooks

通过尝试将钩子传递给常规函数,您违反了它们。虽然这些规则更多的是约定,而不是实际的限制,并且可能在某些情况下起作用(正如此线程中的其他人所提到的)(要么您知道在何处以及为何可以使用它们,或者您不小心满足了它们的使用要求),建议不要这样做以这种方式使用它们。例如,经过一段时间后,您可能会忘记您的函数包含一个钩子,实际上取决于它的声明和使用位置和方式,并将其移动或放入条件中,从而有效地破坏了应用程序的逻辑。

React人员提出了专门的ESlint plugin非常重要,这个custom hook用于在后台分析您的代码,并在您接近违反钩子规则时向您发出警告。这是确定的方式。

如果您仍需要从组件中提取一些与钩子相关的逻辑到单独的函数,请考虑创建一个React.useState

但!

在示例代码中,您没有将钩子传递给函数。 setX是一个钩子,但它返回的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'));不是。你可以随意传递它,而你实际上是要将它传递给你定制的常规功能或自定义钩子!


1
投票

正如规则所述,钩子只能在功能组件的顶部调用,不应该有条件地调用,所以从技术上讲,你可以将它作为函数的参数传递,但是你需要立即执行函数

所以

<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

因此,您不应该以这种方式使用它,因为您可能会发生以后在函数调用中添加一些语句,因此钩子不保留其调用的顺序

维护Hooks调用的顺序是必需的,因为React依赖于钩子调用顺序来维护方法中使用的钩子队列并处理所有进一步的更新

从技术上讲,如果Y(setX)是一个自定义钩子,它本质上是一个从包含顶层钩子的组件中调用的函数


0
投票

在这种情况下,它不是钩子而是传递的setter函数,钩子限制不适用于function Y(setX){ setX('string'); } const Comp = () => { const [X, setX] = useState(''); Y(setX); ... } 。它不一定属于组件范围:

() => Y(setX)

根据用途,它可以从memoization中受益,例如,如果const Comp = () => { const [X, setX] = useState(''); const setY = useCallback(() => Y(setX), []); ... } 应该作为prop传递:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.