最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React: How to wait data before using "this.state.x" into a function? - Stack Overflow

programmeradmin1浏览0评论

I'm currently learning React, and some stuff are not so easy for a newbie...

I have a simple component which renders this (note that it renders a li array thanks to function getSlots):

render () {
    return (
        <ul>
          {this.getSlots(this.state.viewing).map(item => <li key={item}>{item}</li>)}
        </ul>
    )
  }

Function getSlots is:

constructor (props) {...}

getSlots (viewing) {

    SOME STUFF...

    const monday = this.state.house.monday

    return SOME STUFF...
  }

componentDidMount () {...}

render () {...}

The point is that getSlots needs data to be fetched in componendDidMount to work. Indeed, at this time, getSlots doesn't work (it crashes) because it runs before data are fetched (this.state.house.monday is "empty" when it runs).

How do I wait for data to be fetched before running getSlots? Thanks for your clue.

I'm currently learning React, and some stuff are not so easy for a newbie...

I have a simple component which renders this (note that it renders a li array thanks to function getSlots):

render () {
    return (
        <ul>
          {this.getSlots(this.state.viewing).map(item => <li key={item}>{item}</li>)}
        </ul>
    )
  }

Function getSlots is:

constructor (props) {...}

getSlots (viewing) {

    SOME STUFF...

    const monday = this.state.house.monday

    return SOME STUFF...
  }

componentDidMount () {...}

render () {...}

The point is that getSlots needs data to be fetched in componendDidMount to work. Indeed, at this time, getSlots doesn't work (it crashes) because it runs before data are fetched (this.state.house.monday is "empty" when it runs).

How do I wait for data to be fetched before running getSlots? Thanks for your clue.

Share Improve this question asked Dec 16, 2017 at 21:19 charnouldcharnould 2,9074 gold badges23 silver badges31 bronze badges 1
  • 1 Just return an empty array while this.state.house is not what you expect. – Bergi Commented Dec 16, 2017 at 21:29
Add a comment  | 

3 Answers 3

Reset to default 10

You're going to need to conditionally render. Provide a loading state to be loaded prior to asynchronously required data. You'll want something like the following:

class WrapperComponent extends PureComponent {
    constructor(props) {
        super(props);

        this.state = {
            isLoaded: false,
            data: null
        };
    }

    componentDidMount() {
        MyApiCall.then(
            res => this.setState({
                // using spread operator, you will need transform-object-rest-spread from babel or
                // another transpiler to use this
                ...this.state, // spreading in state for future proofing
                isLoaded: true,
                data: res.data
            })
        );
    }

    render() {
        const { isLoaded, data } = this.state;
        return (
            {
                isLoaded ?
                    <PresentaionComponentThatRequiresAsyncData data={ data } /> :
                    <LoadingSpinner /> // or whatever loading state you want, could be null
            }
        );
    }
}
constructor() {
  super()
  this.state = { isLoading: true }
}

componentDidMount() {
  ('fetch data').then(() => { this.setState({ isLoading: false }); })
}

render() {
  return (
    <div>
      {!this.state.isLoading && ('your code')}
    </div>
  );
}

Something like that.

You can initialize the state with empty data before fetching, in constructor like this

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

And put a condition in getSlots method which checks if data is fetched or not

getSlots (viewing) {

    if (!this.state.house) {
       return [];
    }

    SOME STUFF...

    const monday = this.state.house.monday

    return SOME STUFF...
  }

When the data arrives, then simply set the corresponding state like this

componentDidMount(){
   fetch().then((houses) => {
      this.setState({ houses: houses })
   })
}
发布评论

评论列表(0)

  1. 暂无评论