admin管理员组

文章数量:1202394

I am waiting the props to come up from a store named GetDealersStore, and the way I am fetching that data is with an action where I am doing this:

  componentWillMount () { GetDealersActions.getDealers(); }

I already test the app and componentWillMount() is running before the initial render where I have this

let dealerInfo;
if (this.state.dealerData) {
  dealerInfo = this.state.dealerData.dealersData.map((dealer) => {
    return (<div>CONTENT</div>);
  })
} else {
  dealerInfo = <p>Loading . . .</p>
}

but for the first second you can see <p>Loading . . .</p> in the screen which is the else in the conditional above, and then the rest of the render comes up with return (<div>CONTENT</div>); which is the if in the conditional. So, I guess, this means that the render method has been trigger twice because it keeps waiting for the data coming from the database.

The data from the database is not available at the time of the 1st render, so, how can I fetch that data before the 1st initial render occurs?

I am waiting the props to come up from a store named GetDealersStore, and the way I am fetching that data is with an action where I am doing this:

  componentWillMount () { GetDealersActions.getDealers(); }

I already test the app and componentWillMount() is running before the initial render where I have this

let dealerInfo;
if (this.state.dealerData) {
  dealerInfo = this.state.dealerData.dealersData.map((dealer) => {
    return (<div>CONTENT</div>);
  })
} else {
  dealerInfo = <p>Loading . . .</p>
}

but for the first second you can see <p>Loading . . .</p> in the screen which is the else in the conditional above, and then the rest of the render comes up with return (<div>CONTENT</div>); which is the if in the conditional. So, I guess, this means that the render method has been trigger twice because it keeps waiting for the data coming from the database.

The data from the database is not available at the time of the 1st render, so, how can I fetch that data before the 1st initial render occurs?

Share Improve this question edited Oct 14, 2015 at 17:47 Evan Davis 36.6k7 gold badges52 silver badges58 bronze badges asked Oct 14, 2015 at 17:08 NonNon 8,58920 gold badges80 silver badges130 bronze badges 10
  • @Mathletics "nonsense" only because you don't understand it ? I am just a junior developer asking for help. I have tried everything and still don't get it. So sorry, if I bother you, you can ignore the question. EASY! – Non Commented Oct 14, 2015 at 17:28
  • @Mathletics I already debug it, the whole problem I have is that the data from the databse is not available at the time of the 1st render, so, how can I fetch that data before the 1st initial rendering occurs? can you explain me that ? – Non Commented Oct 14, 2015 at 17:32
  • You can't do that from within a component. Remember, the job of React is to RENDER a component; if you have nothing to render, you shouldn't call the component in the first place. – Evan Davis Commented Oct 14, 2015 at 17:40
  • Use getInitialState to default state so that state is created and the render method will not fail. Then this shouldn't be an issue. And, I'd recommend giving facebook.github.io/react/docs/component-specs.html a read if you haven't already. – Jeff S Commented Oct 14, 2015 at 17:42
  • 4 You cannot block the initial render. Use a container component to manage your data and render when ready. – Evan Davis Commented Oct 14, 2015 at 17:44
 |  Show 5 more comments

2 Answers 2

Reset to default 13

You can't do this with a single component. You should follow the Container Component pattern to separate data from rendering.

let DealersContainer = React.createClass({
  getInitialState() {
    return {dealersData: []};
  },
  componentWillMount() {
    GetDealersActions.getDealers();
  },
  render() {
    let {dealersData} = this.state;
    return (<div>
      {dealersData.map((dealer) => {
        let props = dealer;
        return (<Dealer ...props />); // pass in dealerData as PROPS here
      })}
    </div>);
  }
});

Then update your Dealer component to receive props and render the actual content.

My answer is similar to Mathletics', just in more detail.

In this example I've included initialising state of dealerData to null; this is the check that's made to determine whether the data has been returned from the store by the container.

It's verbose, but declarative, and does what you want, in the order that you want, and it will work each time.

const DealerStore = MyDataPersistenceLibrary.createStore({
  getInitialState() {
    return {
      dealerData: null
    };
  },

  getDealers() {
    // some action that sets the dealerData to an array
  }
});

const DealerInfoContainer = React.createClass({
  componentWillMount() {
    DealerStoreActions.getDealers();
  },

  _renderDealerInfo() {
    return (
      <DealerInfo {...this.state} />
    );
  },

  _renderLoader() {
    return (
      <p>Loading...</p>
    );
  },

  render() {
    const { dealerData } = this.state;

    return (
      dealerData
      ? this._renderDealerInfo()
      : this._renderLoader()
    );
  }
});

const DealerInfo = React.createClass({
  getDefaultProps() {
    return {
      dealerData: []
    };
  },

  _renderDealers() {
    const { dealerData } = this.props;

    return dealerData.map(({ name }, index) => <div key={index}>{name}</div>);
  },

  _renderNoneFound() {
    return (
      <p>No results to show!</p>
    );
  },

  render() {
    const { dealerData } = this.props;

    return (
      dealerData.length 
      ? this._renderDealers()
      : this._renderNoneFound()
    );
  }
});

本文标签: javascriptHow can I prevent a component from rendering before data is loadedStack Overflow