Home > Software engineering >  How to return a component in an async method withing a FlatList
How to return a component in an async method withing a FlatList

Time:01-12

I have a functional component

const Foo = () => {
  const _renderSomething = async id => {
    const data = await database.get(SOME_TABLE).Where(someColumnValue = id);        
    return Promise.resolve(
      <AnotherComponent
        data={data} />
    );
  };

  const _renderCard = ({item}) => {
    const {code, id} = item;
    ...
    return (
      <Card
        index={code}>
        {_renderSomething(id)}
      </Card>
    );
  };

  return (
    <FlatList
      data={rawData}
      initialNumToRender={rawData.length}
      keyExtractor={item => item.code}
      renderItem={_renderCard}
    />
  );

Now, this gives me

ERROR Error: Objects are not valid as a React child (found: object with keys {_U, _V, _W, _X}). If you meant to render a collection of children, use an array instead.

Which I do not quite understand.

CodePudding user response:

First, I notice that there is a syntax error in renderCard. This is not valid JSX since the ending tag doesn't match the opening tag and props should be passed into the component like propName={propValue}.

<Card
    index={code}
    {_renderSomething(id)}
</FlipCard>

I assume that maybe you intended to write this

<Card index={code}>
    {_renderSomething(id)}
</Card>

Where you are passing the result of _renderSomething as the Card component's children prop. Which explains that error that you get as async functions are not valid as React child element.

Instead you can refactor _renderSomething into a separate React component and do the data loading within a useEffect hook.

const Something = ({ id }) => {
  const [data, setData] = useState(null);

  useEffect(() => {
     database.get(...).then(setData);
  }, [id])
    
  return (
    <AnotherComponent data={data} />
  );
};

This can then be used within _renderCard like so

const _renderCard = ({item}) => {
  const {code, id} = item;
  ...
  return (
    <Card index={code}>
      <Something id={id} />
    </Card>
  );
};
  • Related