【问题标题】:Can I use dynamic properties in dependency array for useEffect?我可以在依赖数组中使用动态属性来实现 useEffect 吗?
【发布时间】:2020-06-09 05:57:23
【问题描述】:

所以我有一个关于 useEffect 依赖项的问题

这是来自反应文档:

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes

这到底是什么意思,React 是否跟踪 count 变量及其值,并在值更改时做出反应,或者 React 是否跟踪数组中的第一个元素及其值。

这是什么意思?让我再解释一下。因此,如果我们有类似 [name] 的东西作为依赖项。在评估时,数组可能会产生['Bob']['Steve']。显然这是一个改变,useEffect 将重新渲染组件。但是它是如何检查的呢?

它是跟踪name 还是跟踪dependencyArray[0]。如果我们看一下前面的例子,这两个结果都会为真,namefirst element 都将它们的值从'Bob' 更改为'Steve'。但它实际上是如何工作的呢?

目前在我的代码中,我正在使用类似 [employees[selectedEmployee].name] 的东西,其中 selectedEmployee 是 UI 上可点击的东西,它变成了“Bob”或“Steve”

例如:

const employees = {
   Bob: {
      name: 'Bob'
   },
   Steve: {
      name: 'Steve'
   }
}

这意味着最终,在评估时,依赖数组仍然会产生['Bob'] --> ['Steve'],如果 React 正在评估 dependencyArray[0],那么显然已经改变并且组件应该重新渲染,但是如果它跟踪引用,那么我将完全更改引用,这可能会导致问题。

那么正确的方法是什么?我可以使用像employees[selectedEmployee].name 这样的动态属性作为依赖项吗?

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    count 是一个值,而不是一个引用。

    这只是很好的旧 Javascript,没什么花哨的:

    const myArray = [ count ]; // new array containing the value of variable 'count'
    const myFunction = () => {
      document.title = `You clicked ${count} times`;
    }
    
    useEffect(
      myFunction,
      myArray
    );
    
    // Means actually:
    // "Run this function if any value in the array
    // is different to what it was last time this useEffect() was called"
    

    React 是否跟踪 ... 值或 ... 引用?

    React 真正“跟踪”其中任何一个。它只检查与之前调用的差异,而忘记其他所有内容。

    我可以使用动态属性作为依赖项吗?

    是的,你可以(因为它们不像你想象的那样“动态”)

    那么正确的方法是什么?

    最好不要考虑任何反应魔术,但是

    • 理解组件是一个函数,并相信 React 在必要时调用它并且
    • 从简单的 Javascript 角度考虑其中使用的变量(属性和状态)。

    然后您的“动态属性”变成“在一次函数调用期间的常量变量”。无论哪个变量动态变化,如何动态变化,上一次都是一个值,现在是一个值。

    说明:

    这里的重要“技巧”是,该组件只是一个 javascript 函数,它被称为 '只要有任何可能发生变化',因此 @987654323 @ 也被调用(因为 useEffect() 只是组件内部的一个函数调用)。
    只有传递给 useEffect 的回调函数并不总是被调用。

    useEffect渲染组件,useEffect被调用组件被调用,然后只是调用给它的函数,或者不,取决于依赖项数组中的任何值是否与上次调用 useEffect() 时的值不同。

    React 可能如果在给定给 useEffect 的函数中对状态或某些东西(任何使 React 认为它必须重新渲染的东西)进行了任何更改,则重新渲染组件,但这是结果这种状态变化,无论它来自哪里,都不是因为 useEffect 调用。

    示例:

    const MyComponent = (props) => {
    
      // I'm assigning many const here to show we are dealing with local constants.
      // Usually you would use this form (using array destructuring):
      // const [ selectedEmployee, setSelectedEmployee ] = useState( someInitialValue );
    
      const myStateValueAndSetter = useState( 'Bob' );
      const selectedEmployee    = myStateValueAndSetter[0];
      const setSelectedEmployee = myStateValueAndSetter[1];
    
      const employees = {
        Bob: { name: 'Bob' },
        Steve: { name: 'Steve' }
      };
    
      const currentName = employees[ selectedEmployee ].name;
    
      useEffect(() => {
        document.title = 'current name: ' + currentName;
      }, [ currentName ]);
    
      return <MyClickableComponent onClick={( newValue ) => {
        setSelectedEmployee( newValue )
      }}>;
    };
    
    • 点击MyClickableComponent调用当前setSelectedEmployee( newValue )函数。
      (常量 selectedEmployee 没有改变!)
    • MyComponent() 再次被调用。
      (这是一个新的函数调用。所有的常量都消失了!只有 React 在后台存储了一些状态。)
    • 调用useState(),结果存储在一个新的常量selectedEmployee中。
    • 调用useEffect(),并根据selectedEmployee 的先前值和当前值决定是否调用其回调。
      如果没有调用回调并且没有其他任何更改,您可能根本不会注意到发生了任何事情。
    • &lt;MyClickableComponent ... /&gt; 被渲染。

    【讨论】:

    • 所以只是为了澄清 第一点: 如果我们有 2 个用户,他们的两个名字都是 'Bob',如果我们通过 user.name 作为依赖项,会这样吗意思是当我们在 UI 中交换用户时,因为他们的名字相同,useEffect 不会调用它的回调? 第二点 依赖数组从[1,2]切换到[2,1]时useEffect是否被激活?这是否被认为是一种改变,因为之前的所有元素都还在这里,只是它们的位置被交换了? 第三点我应该在依赖数组中使用对象,还是应该只有原始值?
    • 第一点: 正确,user.name 带有两个 'Bob' 不会调用 useEffect 回调。但是例如user 而不是 user.name 将。 第二点:好问题!我认为是的,但这绝不应该发生,因为我相信 useEffect 的理念依赖于不变的顺序。 第三点: 都可以,使用对象和原语。 一般情况,回调中用到的所有对象,都应该放在依赖项中,但是评论太多了。
    猜你喜欢
    • 2020-07-22
    • 1970-01-01
    • 2021-08-20
    • 2014-03-26
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    相关资源
    最近更新 更多