1

My problem is as follows:

I have an asynchronous function that makes a mysql request and, depending on the result of the request, returns a different DIV.

const GetData = async (idAluno, disciplina) => {
  variavel = await confereInicial(idAluno, disciplina.id);
  //console.log(variavel); imprime direitinho, sem problemas

  if (variavel.data.length === 0) {
    return (
      <DivCheckBox
        dads={dados}
        nomeDisciplina={disciplina.title}
        labelDisciplina={disciplina.label}
        id={disciplina.id}
        inicial={0}
      />
    );
  } else {
    return (
      <DivCheckBox
        dads={dados}
        nomeDisciplina={disciplina.title}
        labelDisciplina={disciplina.label}
        id={disciplina.id}
        inicial={1}
      />
    );
  }
};

And this function is called several times (via a map) in the rendering part of the screen. Thus:

return (
  <div>
    {dados.state.nodesPadrao.map((p) => {
      return <GetData idAluno={1} disciplina={p} />;
    })}
  </div>
  ...
);

The problem is that when I compile, it appears "objects are not valid as react child (found: object Promise). If you want to render a collection of children, use an array instead.

What do I do?

2
  • 1
    you could put the promise into component lifecycle method (ex. componentDidMount() ) and use setState method to update the component state. The render method must be synchrone and rely on props and state only. Commented May 26, 2021 at 18:30
  • 1
    Q: How to render an asynchronous function in reactJS? A: Leverage promises! Duplicate question (with details on how to do this): Objects are not valid as a React child (found: [object Promise]) Commented May 26, 2021 at 18:33

2 Answers 2

1

You need to understand the difference between a function (GetData()) and a function component (<GetData .../>).

Function components can't be async, since they implicitly always return a Promise, and you can't return a Promise from a component since you can't render a promise.

You'll need to use the useEffect hook to load the data at component mount time, then render things once it's loaded:

const GetData = ({idAluno, disciplina}) => {
  const [variavel, setVariavel] = React.useState(null);
  React.useEffect(() => {
    confereInicial(idAluno, disciplina.id).then(setVariavel);
  }, [idAluno, disciplina.id]);
  if (variavel === null) {
    // Still loading? You could also return `null` to not render anything.
    return <>Loading</>;
  }
  return (
    <DivCheckBox
      dads={dados}
      nomeDisciplina={disciplina.title}
      labelDisciplina={disciplina.label}
      id={disciplina.id}
      inicial={variavel.data.length === 0 ? 0 : 1}
    />
  );
};
Sign up to request clarification or add additional context in comments.

Comments

0

I had the same problem yesterday. You shouldn't do async stuff in a render function. You should either relay on the state or props.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.