考虑下面的钩子示例
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 类组件中立即重新渲染,如下例所示
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> } }
但我的问题是如何强制上面的功能组件立即用钩子重新渲染?
这可以通过useStateor实现useReducer,因为在内部useState使用useReducer:
useState
useReducer
const [, updateState] = React.useState(); const forceUpdate = React.useCallback(() => updateState({}), []);
forceUpdate不打算在正常情况下使用,仅用于测试或其他突出的情况。这种情况可以以更传统的方式解决。
forceUpdate
setCount是不正确使用的示例,forceUpdate出于setState性能原因是异步的,不应仅仅因为状态更新未正确执行而强制同步。如果一个状态依赖于先前设置的状态,这应该使用更新函数来完成,
setCount
setState
如果您需要根据之前的状态设置状态,请阅读下面的 updater 参数。 <…> updater 函数接收到的 state 和 props 都保证是最新的。更新器的输出与状态浅合并。
如果您需要根据之前的状态设置状态,请阅读下面的 updater 参数。
<…>
updater 函数接收到的 state 和 props 都保证是最新的。更新器的输出与状态浅合并。
setCount可能不是一个说明性示例,因为它的目的尚不清楚,但更新程序功能就是这种情况:
setCount(){ this.setState(({count}) => ({ count: count + 1 })); this.setState(({count2}) => ({ count2: count + 1 })); this.setState(({count}) => ({ count2: count + 1 })); }
这被 1:1 转换为钩子,但用作回调的函数应该更好地被记忆:
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 })); }, []);