简体   繁体   English

reactjs:仅在状态的某些部分更改后渲染完成后才执行脚本

[英]reactjs: execute a script only after render is complete after a certain part of state is changed

I have state like below: 我的状态如下:

this.state = {
data: [ .... ]
misc: [  .... ]
}

I have button when clicked it will fetch data . 我有单击按钮,它将获取data

the data will be fetched using axios and then setState is used to replace the this.state.data 将使用axios提取data ,然后使用setState替换this.state.data

Then as per reactjs render will be called every time you setState to re-render the component if there are changes. 然后,按照reactjs的render will be called every time you setState to re-render the component if there are changes.

After this.state.data is updated, and rendering is complete i want to run a function. 更新this.state.data并完成渲染后,我想运行一个函数。

I dont want to run the function when misc is updated. 我不想在misc更新时运行该功能。 I only want to update when data is updated 我只想在data更新时更新

How to run a function after render only when this.state.data is changed 仅当this.state.data更改时,如何在渲染后运行函数

If you want to restrict rendering on particular state change then just check for that state and return false else return true like: 如果要限制特定状态更改的呈现,则只需检查该状态并返回false,否则返回true,如:

shouldComponentUpdate(nextProps, nextState) {

     if(this.state.misc != nextState.misc) {
          return false
     }
     return true
}

If I understood your question correctly you're talking about the use of lifecycle methods... 如果我正确理解了您的问题,那么您正在谈论生命周期方法的使用...

You should do your data fetching (ajax via axios or the native fetch api) in the componenetDidMount lifecycle hook 您应该在componenetDidMount生命周期挂钩中进行数据获取(通过axios或本机获取api进行ajax)

Something like this: 像这样:

componentDidMount() {
  this.setState({ isLoading: true });

  axios
    .get(url)
    .then(result => this.setState({ data: result.data, isLoading: false }))
    .catch(error => this.setState({ error, isLoading: false }));
}

And your updating in componentDidUpdate More info here: https://reactjs.org/docs/state-and-lifecycle.html 以及您在componentDidUpdate的更新,更多信息请参见: https//reactjs.org/docs/state-and-lifecycle.html

You could use componentDidUpdate ( https://reactjs.org/docs/react-component.html#componentdidupdate ). 您可以使用componentDidUpdate( https://reactjs.org/docs/react-component.html#componentdidupdate )。 This is a lifecycle event that triggers every time the component updates, so you can check if the previous state of data is different than the current state. 这是一个生命周期事件,每次组件更新时都会触发,因此您可以检查数据的先前状态是否不同于当前状态。 I'm assuming data is an array of objects, so to compare them you'll either have to use something to compare like _.isEqual from lodash, or what I've included below will work. 我假设数据是一个对象数组,所以要比较它们,您将不得不使用诸如lodash的_.isEqual之类的东西进行比较,否则我下面包含的内容将起作用。

componentDidUpdate(prevProps, prevState) {
  if(JSON.stringify(prevState.data) !== JSON.stringify(this.state.data)) {
    // Execute your code
  }
}

You need to use componentDidMount() , which will be called after a component is mounted (first render) and componentDidUpdate() , which will be called immediately after updating occurs (but not for the initial render). 您需要使用componentDidMount() (在安装组件后(第一个渲染)之后调用)和componentDidUpdate()在更新发生后立即调用(但不对初始渲染)调用)。

componentDidUpdate takes 3 parameters: prevProps , prevState and snapshot. componentDidUpdate具有3个参数: prevPropsprevState和snapshot。 In your case, you can compare prevState.data against this.state.data to know whether data has been updated: 对于您的情况,可以将prevState.datathis.state.data进行比较,以了解data是否已更新:

 class Main extends React.Component { constructor(props) { super(props); this.counter = 0; this.state = { data: [], misc: 'foo', }; this.changeData = this.handleChangeData.bind(this); this.changeMisc = this.handleChangeMisc.bind(this); } componentDidMount() { console.log('componentDidMount!'); } componentDidUpdate(prevProps, prevState) { if (prevState.data !== this.state.data) { console.log('componentDidUpdate and data has changed!'); } } handleChangeData() { this.setState({ data: [...this.state.data, this.counter++].slice(-10), }); } handleChangeMisc() { this.setState({ misc: this.state.misc === 'foo' ? 'bar' : 'foo', }); } render() { return( <div> <button onClick={this.changeData}>Change data</button> <button onClick={this.changeMisc}>Change misc</button> <pre>DATA = { this.state.data.join(', ') }</pre> <pre>MISC = { this.state.misc }</pre> </div> ); } } ReactDOM.render(<Main />, document.getElementById('app')); 
 .as-console-wrapper { max-height: 106px !important; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM