仅当输入中的所有元素都更改时,如何使 useEffect 挂钩调用提供的效果?

Posted

技术标签:

【中文标题】仅当输入中的所有元素都更改时,如何使 useEffect 挂钩调用提供的效果?【英文标题】:How to make useEffect hook call the provided effect only if all the elements in inputs change? 【发布时间】:2019-07-08 07:54:13 【问题描述】:

我正在尝试将 UNSAFE_componentWillReceiveProps 转换为挂钩。下面是使用CWRP的逻辑。

UNSAFE_componentWillReceiveProps(nextProps)
  if (this.props.val1 !== nextProps.val1 && this.props.val2 !== nextProps.val2) 
    // do something
  

有什么方法可以告诉钩子只有在 val1 和 val2 发生变化时才调用效果。

useEffect(() => 
  // do something only when both inputs change 
, [val1, val2])

【问题讨论】:

How to compare oldValues and newValues on React Hooks useEffect? 可能重复 任何答案对您有用吗?如果是这种情况,请考虑 accepting one of them。 【参考方案1】:

`我猜你可以使用react documents 中提到的自定义钩子:

function usePrevious(value) 
  const ref = useRef();
  useEffect(() => 
    ref.current = value;
  );
  return ref.current;


function MyComponent(val1, val2) 
    let val1Prev = usePrevious(val1);
    let val2Prev = usePrevious(val2);
    useEffect(() => 
        if(val1Prev !== val1 || val2Prev !== val2) 
            // do whatever you want
        
    )

另外,请注意react文档中的这句话:

未来 React 可能会提供一个 usePrevious Hook 开箱即用,因为它是一个相对常见的用例。

【讨论】:

【参考方案2】:

您可以使用useRef 挂钩来存储上次运行效果的道具并与之进行比较。

示例

const  useEffect, useRef  = React;

function MyComponent( val1, val2 ) 
  const lastProps = useRef( val1, val2 );
  useEffect(
    () => 
      if (lastProps.current.val1 !== val1 && lastProps.current.val2 !== val2) 
        console.log("Both changed!");
      

      lastProps.current =  val1, val2 ;
    ,
    [val1, val2]
  );

  return <div> val1 val2 </div>;


class App extends React.Component 
  state =  val1: 1, val2: 1 ;

  componentDidMount() 
    setTimeout(() => this.setState( val1: 2 ), 1000);
    setTimeout(() => this.setState( val2: 2 ), 2000);
    setTimeout(() => this.setState( val1: 3, val2: 3 ), 3000);
  

  render() 
    const  val1, val2  = this.state;
    return <MyComponent val1=val1 val2=val2 />;
  


ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js" ></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" ></script>

<div id="root"></div>

【讨论】:

以上是关于仅当输入中的所有元素都更改时,如何使 useEffect 挂钩调用提供的效果?的主要内容,如果未能解决你的问题,请参考以下文章

仅当所有文本字段都已填写时才在 Swift 中启用按钮

如何在运行时更改布局?

MongoDB - 仅当嵌套数组中的所有条目存在时才更新它们

仅当所有输入都有效时才执行代码

仅当某个元素不等于给定列表中的元素时,如何编写条件语句才能执行? [复制]

仅当使用引导程序填写所有必需的 attr 字段时,如何提交表单?