简体   繁体   中英

When rendering through a helper function I get: “Objects are not valid as a React child” error

I am developing a small project in React Native. I have noticed a weird situation whereby when I render a list through a helper function, I get the eponymous error:

Objects are not valid as a React child

Now this error normally means that I am trying to render an object, which is not the case. I will paste two snippets of code. The first one is how I render the data through a helper function, resulting through an error. The second snippet is how I render the data directly in the render() method and working successfully.

Snippet #1: Rendering through helper function renderUsers() -> does not work

  renderUsers = async () => {
    return this.props.userList.map(
      ({ instructions, address, createdDate, _id }) => (
        <Card
          title={`${moment(createdDate).format("YYYY-MM-DD HH:mm")}`}
          key={_id}
        >
          <Text style={{ marginBottom: 10 }}>{instructions}.</Text>
          <Button backgroundColor="#03A9F4" title="Ready to Help!" />
        </Card>
      )
    );
  };
  ...
  render() {
    return this.props.isFetchingUsers ? null : (
      <View style={{ flex: 1 }}>
        <ScrollView>
          {this.renderUsers()}
        </ScrollView>
      </View>
    );
  }

Snippet #2: Rendering directly inside render() function -> works OK

  render() {
    return this.props.isFetchingUsers ? null : (
      <View style={{ flex: 1 }}>
        <ScrollView>
          {this.props.userList.map(
            ({ instructions, address, createdDate, _id }) => (
              <Card
                title={`${moment(createdDate).format("YYYY-MM-DD HH:mm")}`}
                key={_id}
              >
                <Text style={{ marginBottom: 10 }}>{instructions}.</Text>
                <Button backgroundColor="#03A9F4" title="Ready to Help!" />
              </Card>
            )
          )}
        </ScrollView>
      </View>
    );
  }

What could be the reason?

Your snippet 1 should be like this.

renderUsers = () => {
return this.props.userList.map(
  ({ instructions, address, createdDate, _id }) => (
    <Card
      title={`${moment(createdDate).format("YYYY-MM-DD HH:mm")}`}
      key={_id}
    >
      <Text style={{ marginBottom: 10 }}>{instructions}.</Text>
      <Button backgroundColor="#03A9F4" title="Ready to Help!" />
    </Card>
  )
);
};
...
render() {
  return this.props.isFetchingUsers ? null : (
    <View style={{ flex: 1 }}>
     <ScrollView>
      {this.renderUsers()}
     </ScrollView>
    </View>
  );
}

You need to remove the keyword async

The async function will return Promise Object, which is not supposed to be a React child.

But you no need async function for Array map.

If you want to render something asynchronously try updating state by this.setState and render it accordingly.

You shouldn't return null in render method!

You should render an element like this:

  render() {
    <View style={{ flex: 1 }}>
      <ScrollView>
        { 
          (!this.props.isFetchingUsers && this.props.userList) &&
          this.renderUsers()
        }
      </ScrollView>
    </View>
  }

then remove the keyword async from renderUsers method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM