简体   繁体   中英

When changing react state and conditional rendering, getting: Error: Text strings must be rendered within a <Text> component

I am receiving this error: Error: Text strings must be rendered within a <Text> component. when I update the state, which is a list that contains components. I am trying to add a component, so I don't see why I would need a <Text> component. This list is used to render drawer components that allow the user to view the pages of the clubs they are a part of.

  const [public_list, setPublicList] = useState([]);
  const [private_list, setPrivateList] = useState([]);
  const [list, setList] = useState([]);

  const homeIcon = <Icon name="home-outline" color={'black'} size={20} />;

  var user_doc;

  async function fetchData() {
    user_doc = await firestore()
      .collection('users')
      .doc(auth_user.uid)
      .get()
      .catch(function (error) {
        console.log(
          'There has been a problem with your fetch operation: ' +
            error.message,
        );
      });

    const userData = user_doc['_data'];

    let public_clubList = userData['public_clubs'];
    console.log(user_doc['public_clubs']);

    for (let item = 0; item < public_clubList.length; item++) {
      let name = public_clubList[item]['clubName'];

      const newList = list.concat('hey');

      const newPublicList = public_list.concat(
        <DrawerItem
          icon={({color, size}) => homeIcon}
          label={toString(name)}
          onPress={() => {
            props.navigation.navigate('ClubPage', {hello});
          }}
        />,
      );

      setList(newList);
      setPublicList(newPublicList);

      console.log(name);
    }
    console.log(user_doc['public_clubs'][1]['clubName']);
  }

The error occurs at setList(newList) . I call fetchData during:

useEffect(() => {
    if (list.length == 0) {
      fetchData();
    }
  });

If you were wondering, this is what my userData is:

{"email": "johndoe@email.com", "fullName": "John Doe", "id": "JbuhzofKDEe2ImMl9DPYpBbuVzG2", "private_clubs": [{"clubName": "Kool kids ", "id": "1903440d-e06a-4117-bc41-d27fabb80583"}, {"clubName ": "Test", "id": "53fe982f-318e-4903-a439-9e8271035393"}], "public_clubs": [{"clubName": "Testing adding users n stuff", "id": "a6cb1dcb-cfdd-48a4-b673-671519fbe6dd"}, {"clubName": "Hey guyyys", "id": "c219a611-26c3-44d3-9d66-396b0f9a738d"}], "userName": "johndoe"}

This is what my return statement is. The rest of the drawers load fine.

return (
    <View style={{flex: 1, flexDirection: 'column'}}>
      <DrawerContentScrollView {...props} style={{flex: 10}}>
        <DrawerItem
          icon={({color, size}) => (
            <Icon name="home-outline" color={'black'} size={20} />
          )}
          label={hello}
          onPress={() => {
            props.navigation.navigate('ClubPage', {hello});
          }}
        />
        {list}
        {public_list}
        {private_list}
      </DrawerContentScrollView>
      <Drawer.Section style={{flex: 1}}>
        <DrawerItem
          icon={({color, size}) => (
            <Icon name="buffer" color={'black'} size={20} />
          )}
          label="FeedPage"
          onPress={() => {
            props.navigation.navigate('FeedPage');
          }}
        />
      </Drawer.Section>
      <DrawerItem
        icon={({color, size}) => (
          <Icon name="pen-plus" color={'black'} size={20} />
        )}
        label="Make a Club"
        onPress={() => {
          props.navigation.navigate('MakeClub');
        }}
      />
      <DrawerItem
        icon={({color, size}) => (
          <Icon name="account" color={'black'} size={20} />
        )}
        label="My Profile"
        onPress={() => {
          props.navigation.navigate('ProfilePage');
        }}
      />
    </View>
  );

In this section here, it looks like you're trying to render the list directly onto the jsx:

 <DrawerContentScrollView {...props} style={{flex: 10}}>
        <DrawerItem
          icon={({color, size}) => (
            <Icon name="home-outline" color={'black'} size={20} />
          )}
          label={hello}
          onPress={() => {
            props.navigation.navigate('ClubPage', {hello});
          }}
        />
        {list} // Here
        {public_list} //Here
        {private_list} //Here
      </DrawerContentScrollView>

If your list is an array like it says in the state declaration, map it and render each text separately. Of course it could be an array of objects, in which case you'd need to use the correct key.

{list.map(item => <Text> {item} </Text>)}

Also, try and comment out those lines and add mock values to see the result and check if it is what you expected.

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