How to notify a component that it needs to update

2019-08-18 10:54发布

As you can see in the code below, I check every 100ms (using setInterval) whether a change has been made to convertProgress, and if so, the component needs to update.

class TradingThing extends React.Component {
  componentDidMount() {
    const { convertProgress, setConvertProgress } = this.props.store; // mobx store
    this.interval = setInterval(() => {
         if(convertProgress < 100) {
             setConvertProgress(Math.min(convertProgress + 5, 100));
         }
    , 100);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
        <div>Progress from MobX state: {this.props.store.convertProgress}</div>
    );
  }
}

How can I handle it? Is it okay to call an empty function every 100ms?

Note: I am not allowed to call setStatefunction in render, componentWillUpdate, componentDidUpdate and getSnapshotBeforeUpdate.

1条回答
Summer. ? 凉城
2楼-- · 2019-08-18 11:30

Instead of polling every 100ms, a better approach is to utilize some kind of Publish-Subscribe mechanism. This mechanism allows you to "notify" your component when it needs to update, instead of constantly (and redundantly) checking whether an update is needed.

Events in JavaScript are a good example of the Publish-Subscribe pattern.

There are many ways to implement that, but here is a basic example of the concept:

// This class is utilizing the publish-subscribe pattern
class ProgressUpdater {
  static subscribers = [];

  static publish(progress) {
    this.subscribers.forEach(s => s(progress));
  }

  static subscribe(subscriber) {
    this.subscribers.push(subscriber);
  }
}

Then your process should publish its progress by calling:

ProgressUpdater.publish(progress);

And your component should subscribe to the progress update event in componentDidMount:

class App extends React.Component {
  state = {progress: 0}

  componentDidMount() {
    ProgressUpdater.subscribe(progress => {
        this.setState({progress});
    })
  }

  render() {
    return (
      <div className='progress'>Progress: {this.state.progress}</div>
    )
  }
}

Here's a fiddle to see how it all works together

查看更多
登录 后发表回答