Search code examples
reactjsreact-hooksreact-functional-component

useeffect() run and set data to the variable after the return() run in react? how to handle this?


export default function Education() {
  const classes = useStyles();
  const [projects, setProjects] = useState({});

  useEffect(() => {
    axios.get("http://127.0.0.1:8000/api/").then((res) => {
      setProjects(res.data);
      console.log(res.data);
    });
  }, [projects]);

  return (
    <div className={classes.root}>
      <Grid container spacing={3}>
        <Grid item xs={12} sm={12}>
          <Typography variant="h4" color="secondary">
            Some of my work
          </Typography>
        </Grid>

        {projects.map((project) => {
          return <p key={project.id}>{project.name}</p>;
        })}

      </Grid>
    </div>
  );
}

I want to get data from the api whenever the page gets render but what is happening is,

  1. the variable project initialized with null
  2. the return () runs where projects.map() function is.
  3. As projects variable does not have any data so the map is not a valid function to run on projects.
  4. And then the useeffect() is running.

thats why i'm getting Error:

TypeError: projects.map is not a function

how can i solve this. i'm new to react. Can anyone help me.


Solution

  • you don't need to specify project in the useEffect, just use an empty array. Since you are using useState and storing the value of project. Keeping it on useEffect will made an infinite call. Also check for projects.length while using map function

    useEffect(() => {
     axios.get("http://127.0.0.1:8000/api/").then((res) => {
      setProjects(res.data);
      console.log(res.data);
     });
    }, []);
     return (
      <div className={classes.root}>
      <Grid container spacing={3}>
        <Grid item xs={12} sm={12}>
          <Typography variant="h4" color="secondary">
            Some of my work
          </Typography>
        </Grid>
    
        {projects.length && projects.map((project) => {
          return <p key={project.id}>{project.name}</p>;
        })} 
    
      </Grid>
    </div>
    );