简体   繁体   English

React.js:在组件安装之前如何获取要加载的数据?

[英]Reactjs: How to fetch data to loaded before the component is mounted?

Something weird is happening, I've been reading the React docs and they talk about the lifecycle and how you can do somestuff before your component is rendered. 发生了一些奇怪的事情,我一直在阅读React文档,他们谈论了生命周期以及如何在呈现组件之前进行一些操作。 I am trying, but everything I try is failing, always the component makes the render first and after calls componenWillMount, ..didMount, etc.. and after the call of those functions, the render happens again. 我正在尝试,但是我尝试的所有尝试都失败了,总是该组件首先进行渲染,然后调用componenWillMount,.. didMount等。在调用这些函数之后,渲染再次发生。

I need to load the data first in order to fill the state because I don't want initial state to be null , I want it with data since the initial rendering. 我需要先加载数据以填充状态,因为我不希望初始状态为null ,而是希望自初始渲染以来将其与数据一起使用。

I am using Flux and Alt, here is the 我正在使用Flux和Alt,这是

action 行动

@createActions(flux)
class GetDealersActions {

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

  getDealers (data) {
    const that = this;
    that.dispatch();
    axios.get(`${API_ENDPOINT}/get-dealers/get-dealers`)
      .then(function success (response) {
        console.log('success GetDealersActions');
        that.actions.dealerDataSuccess({...response.data});
      })
  }
}

then the store 然后是商店

@createStore(flux)
class GetDealersStore {

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

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

}

and the component 组件

@connectToStores
export default class Dealers extends Component {

  static propTypes = {
    title : React.PropTypes.func,
  }

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

  constructor (props) {
    super(props);
    this.state = {
      modal : false,
      dealerData : this.props.dealerData,
    }
  }

  componentWillMount () {
    GetDealersActions.getDealers();
    this.setState({
      dealerData : this.props.dealerData.dealersData,
    })
  }

  static getStores () {
    return [ GetDealersStore ];
  }

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

  render () {

    return (<div>
          <div style={Styles.mainCont}>
            {!!this.props.dealerData ?
              this.props.dealerData.dealersData.map((dealer) => {
                return (<div>HERE I AM RENDERING WHAT I NEED</div>);
              }) : <p>Loading . . .</p>
            }
          </div>
      </div>
    );
  }

}

as you can see in the component part I have this 正如您在组件部分中看到的那样

  constructor (props) {
    super(props);
    this.state = {
      modal : false,
      dealerData : this.props.dealerData,
    }
  }

  componentWillMount () {
    GetDealersActions.getDealers();
    this.setState({
      dealerData : this.props.dealerData.dealersData,
    })
  }

which is telling me that dealerData is undefined or can not read property of null . 这告诉我dealerData is undefinedcan not read property of null

All I need is to know a technique where I can fetch the data before the initial renders occurs. 我所需要的就是了解一种可以在初始渲染发生之前获取数据的技术。 So I can filled out the state and the start working with that data. 因此,我可以填写state并开始使用该数据。

React does guarantee that state assignments in componentWillMount will take place before the first render. React确实保证componentWillMount中的状态分配将在第一个渲染之前进行。 As you well stated in the comments: 正如您在评论中指出的那样:

Invoked once, both on the client and server, immediately before the initial rendering occurs. 在初始渲染发生之前立即在客户端和服务器上调用一次。 If you call setState within this method, render() will see the updated state and will be executed only once despite the state change. 如果在此方法中调用setState,则render()将看到更新后的状态,并且即使状态发生更改也将仅执行一次。

However, the asynchronous actions requested there will not immediately update your store. 但是,在那里请求的异步操作不会立即更新您的商店。 Calling GetDealersActions.getDealers(); 调用GetDealersActions.getDealers(); will issue that the store is updated with new content, but the response will only arrive later in the event queue. 将发出使用新内容更新商店的信息,但响应将仅在事件队列中稍后到达。 This means that this.props.dealersData does not change during the function and setState will attempt to read property "dealersData" of an undefined property. 这意味着this.props.dealersData在函数期间不会更改,并且setState将尝试读取未定义属性的属性“ dealersData”。 Regardless, the requested content cannot be visible at the first render. 无论如何,请求的内容在第一次渲染时将不可见。

My advice is the same as the one in a similar question . 我的建议与类似问题中的建议相同。 Preventing the component from rendering that content until it becomes available, as you did, is an appropriate thing to do in a program. 像您所做的那样,阻止组件在内容可用之前就渲染该内容是在程序中要做的适当事情。 Alternatively, render a loader while your "dealersData" hasn't arrived. 或者,在您的“ dealersData”尚未到达时渲染加载程序。


For solving your particular problem, remove that setState from componentWillMount . 为了解决您的特定问题,请从componentWillMount删除该setState All should work well if your parent component is properly listening for changes and propagating them to the children's props. 如果您的父级组件正在正确地听取更改并将其传播给孩子的道具,那么所有这些都应该工作良好。

componentWillMount () {
  GetDealersActions.getDealers();
}

The best answer I use to receive data from server and display it 我用来从服务器接收数据并显示它的最佳答案

constructor(props){
        super(props);
        this.state = {
            items2 : [{}],
            isLoading: true
        }

    }

componentWillMount (){
 axios({
            method: 'get',
            responseType: 'json',
            url: '....',

        })
            .then(response => {
                self.setState({
                    items2: response ,
                    isLoading: false
                });
                console.log("Asmaa Almadhoun *** : " + self.state.items2);
            })
            .catch(error => {
                console.log("Error *** : " + error);
            });
    })}

 render() {
   return(
       { this.state.isLoading &&
                    <i className="fa fa-spinner fa-spin"></i>

                }
                { !this.state.isLoading &&
            //external component passing Server data to its classes
                     <TestDynamic  items={this.state.items2}/> 
                }
         ) }

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

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