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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With