簡體   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