简体   繁体   中英

Objects are not valid as a React child - use array instead

So I realize that objects can't be rendered, but I am having a hard time figuring out how to fix this error after trying to add a loading spinner when fetching data. Once I added the ternary operator, the data no longer passed to my child component and gave me the error code above. Any help would be appreciated.

const Dashboard = () => {
  const [isLoading, setLoading] = useState(false);
  const [marsData, setMarsData] = useState([]);

  const getMarsData = useCallback(async () => {
    try {
      setLoading(true);

      const res = await fetch('/api/nasa/mars');

      if (res.ok) {
        const jsosData = await res.json();
        setMarsData(jsosData.photos.slice(1, 6));
      } else {
        throw new Error(res.statusText);
      }
    } catch (err) {
      console.error(err);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => console.log(marsData), [marsData]);

  useEffect(() => {
    getMarsData();
  }, [getMarsData]);

 return (
    <div>
      {isLoading ? (
        marsData
      ) : (
        <Col s={4}>
          <Preloader active color="blue" flashing={false} size="big" />
        </Col>
      )}
      <MarsRoverPhotos data={marsData} />

      <MarsWeather />
    </div>
  );
};

And here is my MarsRoverPhotos component

const MarsRoverPhotos = ({data}) => {
  return (
    <div>
      <Slider
        fullscreen={false}
        options={{
          duration: 500,
          height: 400,
          indicators: true,
          interval: 6000,
        }}
      >
        {data.map((d) => (
          <Slide image={<img key={d.id} alt="" src={d.img_src} />}>
            <Caption
              placement="right"
              style={{height: '30px', paddingTop: '175px'}}
            >
              <h3>{d.camera.name}</h3>
              <h5 className="light grey-text text-lighten-3">
                {d.camera.full_name}
              </h5>
            </Caption>
          </Slide>
        ))}
      </Slider>
    </div>
  );
};

The error it's telling exactly what to do:

Can't see what you are doing with this component:

<MarsRoverPhotos data={marsData} />

But you are passing the response from jsosData.photos.slice(1, 6) which its an object not an array, so React is complaining that you are trying to render object, but React don't know what to do with it.

Probably inside of <MarsRoverPhotos data={marsData} /> you have something like:

return (<div>{marsData}</div>) // <-- that its rendering an object

The solution:

You should check what are your receiving on jsosData.photos.slice(1, 6) most likely you are a receiving something like:

{
  "someId1": { value: "imgSrc" },
  "someId2": { value: "imgSrc"}
}

So what you need to do its iterate over the object the easy and standard way its:

function MarsRoverPhotos(props) {
   const {data} = props;

    return Object.keys(data).map(key => <div>{data[key].value}</div>)
}

And you should be able to render your component. cheers!

Not sure if it's the most efficient way, but I did seem to solve it via a more basic approach to conditional rendering.

if (isLoading) {
    return (
      <div>
        <Col s={4}>
          <Preloader active color="blue" flashing={false} size="big" />
        </Col>
      </div>
    );
  } else {
    return (
      <div>
        <MarsRoverPhotos data={marsData} />
      </div>
    );
  }

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