为什么渲染后会调用componentWillMount? [英] Why componentWillMount is called after rendering?

查看:61
本文介绍了为什么渲染后会调用componentWillMount?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与React合作,并试图了解其生命周期.我正在执行 componentWillMount 方法,以便在渲染发生之前获取所需的 props .我需要知道如何在加载视图时更新状态.

I am working with React and I am trying to understand the lifecycle. I am doing a componentWillMount method in order to get the props I need before the render occurs. I need to know how to update the state when the view loads.

我想要做的只是一个 GET 请求,以获取赌场游戏的发牌者列表.基本上,我缺少用于在DOM中呈现经销商列表的1或2个步骤

All I am trying to do is a GET request in order to get a list of dealers for a Casino Game. Basically, I am missing 1 or 2 steps which are for render the dealers's list in the DOM

我将展示我在用代码做什么,然后我将解释我想要的东西

I will show what I am doing with my code and after that I will explain what I want

动作部分

getDealerActions.js

class GetDealersActions {

  constructor () {
    this.generateActions('dealerDataSuccess', 'dealerDataFail');
  }

  getDealers (data) {
    const that = this;
    that.dispatch();
    axios.get('someroute/get-dealers/get-dealers')
      .then(function success (response) {
        that.actions.dealerDataSuccess({...response.data});
      })
  }
};

然后我们去商店

getDealersStore.js

class GetDealersStore {

  constructor () {
    this.state = {
      dealerData : null,
    };
  }

  @bind(GetDealersActions.dealerDataSuccess)
  dealerDataSuccess (data) {
    this.setState({
      dealerData : data,
    });
   console.log(this.state.dealerData);
  }
}

在这种情况下, console.log(this.state.dealerData); 返回的正是我所需要的

in this case that console.log(this.state.dealerData); returns something like this which is exactly what I need

Object {dealersData: Array[3]}

老实说,问题出在组件部分,因为我不知道如何在这里处理数据

the problems comes in the component part, honestly because I don't know how to handle the data here

@connectToStores
export default class Dealers extends Component {

  static contextTypes = {
    router : React.PropTypes.func,
  }

  constructor (props) {
    super(props);
    this.state = {}
  }

  static getStores () {
    return [ GetDealersStore ];
  }

  static getPropsFromStores () {
    return GetDealersStore.getState();
  }

  componentWillMount () {
    console.log('@@@', this.props);
    GetDealersActions.getDealers();
  }

  render () {
    console.log('>>>', this.props);
    let content;
    if (this.state.dealerData) {
      content = this.state.dealerData.map((item) => {
        return <div key={item.CardId}>{item}</div>;
      });
    } else {
      content = <div>Loading . . .</div>;
    }

    return (
      <div>
        <div>{content}</div>
      </div>
    );
  }

}

我在这里得到的所有÷> {content}</div> Loading...是因为 this.state 像这样 Object {}

all I get here <div>{content}</div> is Loading . . . because this.state is coming like this Object {}

我在这里遇到的一种奇怪的情况是,此视图正在渲染两次,第一次是渲染,而 console.log('>>>',this.props); 返回此>>>对象{params:Object,query:Object} ,并在第二次渲染时触发此>>>对象{参数:对象,查询:对象,DealerData:对象} ,这是我需要的.

A weird situation I am getting here, is that this view is rendering twice, the 1st time is rendering, and the console.log('>>>', this.props); returns this >>> Object {params: Object, query: Object} and the second time it renders, fires this >>> Object {params: Object, query: Object, dealerData: Object} which is what I need.

那么,为什么 componentWillMount 正在等待render方法以便被触发?

So, why componentWillMount is waiting the render method in order to get fired ?

推荐答案

一点也不奇怪. componentWillMount 将在渲染之前触发,并且在第一遍中,您正在调用一个操作来获取经销商 GetDealersActions.getDealers(); ,这基本上是一个异步命令.由于它是异步的,因此该组件将在获取数据之前渲染一次,然后在商店发布 changed 事件之后再次渲染,该事件将重新触发渲染.

It's not weird at all. componentWillMount will fire before render, and in the first-pass you are invoking an action to get the dealers GetDealersActions.getDealers(); which is basically an async command. Since it is async, the component will render once before it gets data, and then again after the store publishes a changed event, which will re-trigger rendering.

这是您的示例中发生的一系列动作的近似值:

Here is an approximation of the sequence of actions happening in your example:

  1. componentWillMount 调用 getDealers 命令(异步)
  2. 具有默认组件状态的初始 render
  3. 在操作创建者和存储中完成的异步操作是通过经销商数据设置的
  4. 商店发布了一个 changed 事件,该事件重新触发了渲染
  5. 在组件状态下使用经销商数据调用的
  6. 第二次 render .
  1. componentWillMount invokes getDealers command (which is async)
  2. initial render with default component state
  3. Async operation completed in action creator and store is set with dealer data
  4. store publishes a changed event, which re-triggers rendering
  5. second render invoked with the dealer data in component state.

问题在于React将按一定顺序运行其生命周期方法,而不关心您调用某些异步方法.因此,基本上,您没有一种方法可以停止 rendering ,只是因为您调用了一个命令来获取 dealers .这是 react (或功能)的局限性,与异步编程结合使用时会浮出水面,您应该原样接受它.

The problem is that React will run it's lifecycle methods in a certain sequence, not caring about you invoking some async method. So basically you don't have a way to stop rendering just because you invoked a command to get the dealers. That is a limitation of react (or a feature), which surfaces when combined with async programming and you should accept it as is.

如果您接受React将渲染两次的事实,则可以利用它,这对您有利,因此在第一次渲染时,您可以仅显示一个 loading 指示符(例如,一个纺车),以及何时显示数据.加载后,只需将其显示在第二个 render 中即可.

If you accept the fact that React will render twice, you can utilize that in your favor, so on first render you could just show a loading indicator (e.g. a spinning wheel) and when the data loads you just display it in the second render.

但是,如果您不确信并仍然希望避免在初始加载中出现双重渲染,则可以在装入应用程序组件之前进行数据的预取,这将确保在加载初始数据之前将初始数据加载到存储中.第一个 render ,这意味着您不必在 componentWillMount 中调用 getDealers ,因为数据已经在第一个 render .

However, if you are not convinced and still want to avoid double-rendering in the initial load, you could do prefetching of the data before you mount the application component, which would ensure that initial data is loaded in the store before the first render, which would mean that you wouldn't have to invoke getDealers in componentWillMount since the data would already be in the store on the first render.

提醒一下,双重渲染并不是一个显着的性能问题,就像在Angular.js或Ember.js中那样,因为React在DOM操作方面非常有效,但是如果处理不当,可能会产生一些UX问题.

As a reminder, double-rendering is not a significant performance problem, like it would be in Angular.js or Ember.js, since React is very efficient at DOM manipulation, but it could produce some UX issues if not handled properly.

这篇关于为什么渲染后会调用componentWillMount?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆