1

I am calling an asynchronous function, and based off that response, the function should be returning a different React Native Element. I have written simpler code that creates the same error.

async function doNothing(){ };


class RouterComponent extends Component {

    render() {
        return(
            doNothing().then(()=> {
                return(
                    <View></View>
                );
            })

The error I am getting is

A Valid React element or (null) must be returned. You may have returned undefined, an array, or some other invalid object.

I am returning a valid React element within the .then(statement). How would I change it so it returns the React Element.

Tan
  • 43
  • 4
  • 2
    if we were to consider the code as it is written , it wil return the async object and not a valid React element. You'd be better off moving the async operation to someother lifecycle method ,like componentDidMount . – semuzaboi Sep 27 '17 at 02:55
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Patrick Roberts Sep 27 '17 at 10:12

2 Answers2

2

If you want to perform async operation in the same file, then move async call to some lifecycle method like ComponentDidMount. Define a state object in constructor,

constructor(props) {
  super(props);
  this.state = {ComponentToRender: ''}
}

Trigger network call from you componentDidMount method,

componentDidMount() {
  doNothing().then(()=> {
     this.setState({
       ComponentToRender: <ComponentToRenderBasedOnResponse>
     })
  })
}

Your render method should use this.state.ComponentToRender method to decide, which component to render.

render() {
  if(this.state.ComponentToRender === 'A') {
    return this.renderComponentA();
  }
  else {
    return null;
  }
}

You can decide, how you want to organize your render method.

ggsrivas
  • 583
  • 7
  • 19
2

In this case render function is not a asncy function. so render function would not wait for your doNothing finishes. So it returns null. You can probably try something like this.

constructor(props) {
  super(props);
  this.state = { renderA: false, renderB: false }
}

componentDidMount() {
  doNothing().then((res)=> {
    if (res.Something){
      this.setState({ renderA: true })
    }
  });
}

renderA() {
  return (<View> view for A </View>);
}

renderB(){
  return (<View> view for B </View>);
}

render() {
  this.state.renderA ? this.renderA() : null;
  this.state.renderB ? this.renderB() : null;
}
csath
  • 1,248
  • 11
  • 25