How to use forceUpdate() correctly?

2019-05-23 17:27发布

问题:

I'm trying to periodically reload an iframe but i'm using React so i can't manipulate the DOM directly. It seems like my best option is to use forceUpdate() because the url isn't changing so i can't use a state change to update it (See previous post here What's the best way to periodically reload an iframe with React?). However when i try doing a forceUpdate() it doesn't re-render my component. Any ideas as to why?

var Graph = React.createClass({
componentDidMount: function() {
    setInterval(function(){
        this.forceUpdate();
    }.bind(this), 5000);
},
render() {
    return (
        <iframe src="http://play.grafana.org/dashboard/db/elasticsearch-metrics" width="1900px" height="700px"/>
    )
}

});

See the codepen here: http://codepen.io/anon/pen/ggPGPQ

**I know grafana can be set to auto update, i'm just using this as an example iframe.

回答1:

React is intelligent to know that that element hasn't changed so it doesn't unmount it on rerender. There are many ways you can remove the element and add it back but here is one contrived way built on your example (renders twice on each interval to remove and add back the iframe):

var Graph = React.createClass({
    getInitialState: function() {
      return {count: 0};
    },
    componentDidMount: function() {
        setInterval(function(){
            this.setState({count: this.state.count + 1});
            this.setState({count: this.state.count + 1});
        }.bind(this), 5000);
    },
    render() {
        return this.state.count % 2 === 0 ? (
          <iframe src="http://play.grafana.org/dashboard/db/elasticsearch-metrics" width="1900px" height="700px"/>
        ) : null;
    }
});

ReactDOM.render((
    <div style={{height:'100%'}}>
        <Graph />
    </div>
), document.getElementById('root'));


回答2:

class App extends React.Component {
    state = {
        name: 'request',
        phones: ['nokia', 'sonya', 'ericsson']
    }

     Rerender = () => {
        this.forceUpdate()
     }

    render() {
        const rd= Math.random();
        return ( <div> REACT APP
            { this.state.phones.map(item => <p>{item} {rd}</p>) }

            <input type="button" value="Click" onClick={this.Rerender}/>
        </div>)
    }
}
ReactDom.render(
        <App />,
    document.getElementById('root')
);