繁体   English   中英

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

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

发生了一些奇怪的事情,我一直在阅读React文档,他们谈论了生命周期以及如何在呈现组件之前进行一些操作。 我正在尝试,但是我尝试的所有尝试都失败了,总是该组件首先进行渲染,然后调用componenWillMount,.. didMount等。在调用这些函数之后,渲染再次发生。

我需要先加载数据以填充状态,因为我不希望初始状态为null ,而是希望自初始渲染以来将其与数据一起使用。

我正在使用Flux和Alt,这是

行动

@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});
      })
  }
}

然后是商店

@createStore(flux)
class GetDealersStore {

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

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

}

组件

@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>
    );
  }

}

正如您在组件部分中看到的那样

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

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

这告诉我dealerData is undefinedcan not read property of null

我所需要的就是了解一种可以在初始渲染发生之前获取数据的技术。 因此,我可以填写state并开始使用该数据。

React确实保证componentWillMount中的状态分配将在第一个渲染之前进行。 正如您在评论中指出的那样:

在初始渲染发生之前立即在客户端和服务器上调用一次。 如果在此方法中调用setState,则render()将看到更新后的状态,并且即使状态发生更改也将仅执行一次。

但是,在那里请求的异步操作不会立即更新您的商店。 调用GetDealersActions.getDealers(); 将发出使用新内容更新商店的信息,但响应将仅在事件队列中稍后到达。 这意味着this.props.dealersData在函数期间不会更改,并且setState将尝试读取未定义属性的属性“ dealersData”。 无论如何,请求的内容在第一次渲染时将不可见。

我的建议与类似问题中的建议相同。 像您所做的那样,阻止组件在内容可用之前就渲染该内容是在程序中要做的适当事情。 或者,在您的“ dealersData”尚未到达时渲染加载程序。


为了解决您的特定问题,请从componentWillMount删除该setState 如果您的父级组件正在正确地听取更改并将其传播给孩子的道具,那么所有这些都应该工作良好。

componentWillMount () {
  GetDealersActions.getDealers();
}

我用来从服务器接收数据并显示它的最佳答案

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