考虑下面的钩子示例

   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>
        }
 }

但我的问题是,我如何才能强制上述功能组件重新渲染立即与挂钩?


当前回答

React Hooks FAQ官方解决方案的forceUpdate:

const [_, forceUpdate] = useReducer((x) => x + 1, 0);
// usage
<button onClick={forceUpdate}>Force update</button>

工作示例

const App = () => { const [_, forceUpdate] = useReducer((x) => x + 1, 0); return ( <div> <button onClick={forceUpdate}>Force update</button> <p>Forced update {_} times</p> </div> ); }; ReactDOM.render(<App />, document.getElementById("root")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.1/umd/react.production.min.js" integrity="sha256-vMEjoeSlzpWvres5mDlxmSKxx6jAmDNY4zCt712YCI0=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.1/umd/react-dom.production.min.js" integrity="sha256-QQt6MpTdAD0DiPLhqhzVyPs1flIdstR4/R7x4GqCvZ4=" crossorigin="anonymous"></script> <script>var useReducer = React.useReducer</script> <div id="root"></div>

其他回答

React Hooks FAQ官方解决方案的forceUpdate:

const [_, forceUpdate] = useReducer((x) => x + 1, 0);
// usage
<button onClick={forceUpdate}>Force update</button>

工作示例

const App = () => { const [_, forceUpdate] = useReducer((x) => x + 1, 0); return ( <div> <button onClick={forceUpdate}>Force update</button> <p>Forced update {_} times</p> </div> ); }; ReactDOM.render(<App />, document.getElementById("root")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.1/umd/react.production.min.js" integrity="sha256-vMEjoeSlzpWvres5mDlxmSKxx6jAmDNY4zCt712YCI0=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.1/umd/react-dom.production.min.js" integrity="sha256-QQt6MpTdAD0DiPLhqhzVyPs1flIdstR4/R7x4GqCvZ4=" crossorigin="anonymous"></script> <script>var useReducer = React.useReducer</script> <div id="root"></div>

我对forceUpdate的变化不是通过计数器,而是通过一个对象:

// Emulates `forceUpdate()`
const [unusedState, setUnusedState] = useState()
const forceUpdate = useCallback(() => setUnusedState({}), [])

因为{}!=={}每次。

单行解决方案:

const [,forceRender] = useReducer((s) => s+1, 0)

你可以在这里了解useReducer。 https://reactjs.org/docs/hooks-reference.html#usereducer

一句话解决方案:

useState()[1];

useState返回一对值:当前状态和更新状态的函数——state和setter,这里我们只使用setter来强制重新呈现。

潜在的选项是仅在特定组件上使用键强制更新。更新键会触发组件的呈现(之前更新失败)

例如:

const [tableKey, setTableKey] = useState(1);
...

useEffect(() => {
    ...
    setTableKey(tableKey + 1);
}, [tableData]);

...
<DataTable
    key={tableKey}
    data={tableData}/>