Igor Ferreira
Igor Ferreira

Reputation: 35

How to render a component after setState in React?

I know this is a common question, but after hours of searching for an answer, I decided to ask for help.

I'm trying to pass a state variable to a component, but the component was rendered before the value was set

my code:

import React, { useState, useEffect } from "react";
import { useLocation } from "react-router-dom";
import Seguradora from "../../components/seguradora/seguradora.component";

const CorretorasShow = () => {
  const obj = useLocation();
  const [names, setNames] = useState([]);

  useEffect(() => {
    const url =
      "http://localhost:3001/corretoras/63338f415c502044e953d408" +
      obj.state._id;

    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const json = await response.json();
        setNames(json.seguradora); // <<<<<< setState
      } catch (error) {
        console.log("error", error);
      }
    };

    fetchData();
  }, []);

  return (
    <div>
      <Seguradora props={names} /> //<<<<< state varible
    </div>
  );
};

I've tried useMemo, useRef and ternary operator to no avail. I'm not an expert programmer and I'm new to reactJS so I may have done something wrong with these workarounds

Upvotes: 1

Views: 105

Answers (2)

Jovana
Jovana

Reputation: 608

Since fetching data is async action, fetched data, in this case names, will be undefined at the moment of rendering child component. To avoid that, you need to check if names array has values and render child component only if that's true.

import React, { useState, useEffect } from "react";
import { useLocation } from "react-router-dom";
import Seguradora from "../../components/seguradora/seguradora.component";

const CorretorasShow = () => {
  const obj = useLocation();
  const [names, setNames] = useState([]);

  useEffect(() => {
    const url =
      "http://localhost:3001/corretoras/63338f415c502044e953d408" +
      obj.state._id;

    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const json = await response.json();
        setNames(json.seguradora); // <<<<<< setState
      } catch (error) {
        console.log("error", error);
      }
    };

    fetchData();
  }, []);

  return (
    <div>
      { names.length !== 0 && <Seguradora props={names} /> }
    </div>
  );
};

Upvotes: 0

Caio Amorim
Caio Amorim

Reputation: 308

Since names is an Array, you can check if the Array is populated to conditionally render your component, like this:

return (
    <div>
      { names.length > 0 ?  <Seguradora props={names} /> : null} 
    </div>
  );

Upvotes: 2

Related Questions