我该如何在React中强制使用钩子重新渲染组件?

我该如何在React中强制使用钩子重新渲染组件?

问题描述:

考虑以下钩子示例

   import { useState } from 'react';

   function Example() {
       const [count, setCount] = useState(0);

       return (
           <div>
               <p>You clicked {count} times</p>
               <button onClick={() => setCount(count + 1)}>
                  Click me
               </button>
          </div>
        );
     }

基本上,我们使用this.forceUpdate()方法强制组件在React类组件中立即重新呈现,如下面的示例

Basically we use this.forceUpdate() method to force the component to re-render immediately in React class components like below example

    class Test extends Component{
        constructor(props){
             super(props);
             this.state = {
                 count:0,
                 count2: 100
             }
             this.setCount = this.setCount.bind(this);//how can I do this with hooks in functional component 
        }
        setCount(){
              let count = this.state.count;
                   count = count+1;
              let count2 = this.state.count2;
                   count2 = count2+1;
              this.setState({count});
              this.forceUpdate();
              //before below setState the component will re-render immediately when this.forceUpdate() is called
              this.setState({count2: count
        }

        render(){
              return (<div>
                   <span>Count: {this.state.count}></span>. 
                   <button onClick={this.setCount}></button>
                 </div>
        }
 }

但是我的查询是如何强制上述功能组件立即通过钩子重新渲染?

But my query is How can I force above functional component to re-render immediately with hooks?

由于

This is possible with useState or useReducer, since useState uses useReducer internally:

const [, updateState] = React.useState();
const forceUpdate = React.useCallback(() => updateState({}), []);

forceUpdate不能在正常情况下使用,仅在测试或其他突出情况下使用.这种情况可能会以更常规的方式解决.

forceUpdate isn't intended to be used under normal circumstances, only in testing or other outstanding cases. This situation may be addressed in a more conventional way.

setCount是未正确使用forceUpdate的示例,出于性能原因,setState是异步的,不应仅因为状态更新未正确执行而被迫同步.如果状态依赖于先前设置的状态,则应使用更新程序功能来完成,

setCount is an example of improperly used forceUpdate, setState is asynchronous for performance reasons and shouldn't be forced to be synchronous just because state updates weren't performed correctly. If a state relies on previously set state, this should be done with updater function,

如果您需要根据先前的状态来设置状态,请阅读以下有关updater参数的信息.

If you need to set the state based on the previous state, read about the updater argument below.

< ...>

<...>

由updater函数接收的状态和道具均得到保证 是最新的.更新程序的输出与 状态.

Both state and props received by the updater function are guaranteed to be up-to-date. The output of the updater is shallowly merged with state.

setCount可能不是说明性的示例,因为其用途尚不清楚,但更新程序功能就是这种情况:

setCount may not be an illustrative example because its purpose is unclear but this is the case for updater function:

setCount(){
  this.setState(({count}) => ({ count: count + 1 }));
  this.setState(({count2}) => ({ count2: count + 1 }));
  this.setState(({count}) => ({ count2: count + 1 }));
}

这将1:1转换为钩子,但最好将用作回调的函数记住:

This is translated 1:1 to hooks, with the exception that functions that are used as callbacks should better be memoized:

   const [state, setState] = useState({ count: 0, count2: 100 });

   const setCount = useCallback(() => {
     setState(({count}) => ({ count: count + 1 }));
     setState(({count2}) => ({ count2: count + 1 }));
     setState(({count}) => ({ count2: count + 1 }));
   }, []);