Search code examples
reactjstypescriptredux

add setState inside useEffect


I have a project and there is a “login” page on it, and after the user clicks on “login”, an interface should appear with all the lists for this user.

And in order for this data to appear immediately after the login process, I used "useEffect" and used the "GetAllListsAction" action that connects with the backend to fetch the data.

Note that I am using typescript.

And after searching, I found that several sites write this logic and they use "useState" and then use "setList" within the "use effect".

Like this example I got from a site:

 const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [])

But I use React with TypeScript, and my coding method is slightly different by coding within the sites.

The problem or question is that I did not know why they used (setList) inside useEffect and I did not know how to add it to my code.

my code is:

import { Grid } from "@material-ui/core";
import SingleList from "./single-list";
import { useStyle } from "../../../../styles/list-styles";
import Header from "../../header-footer/header";
import ListModal from "../modals/list-modal";
import { useEffect } from "react";
import { bindActionCreators } from "redux";
import { Actions } from "../../../../redux-store/actions/actions";
import { connect } from "react-redux";
import { ListItem } from "../../../../redux-store/reducers/todo-list-reducer";

const Lists: React.FC<{ TodoListList: any; GetAllListsAction: Function }> = ({
  GetAllListsAction,
  TodoListList,
}) => {
  const classes = useStyle();

  useEffect(() => {
    // call action to fetch lists
    GetAllListsAction();
  }, []);

  return (
    <>
      <Header />

      <Grid className={classes.grid}>
        <Grid
          container
          className={classes.addButton}
          item
          direction="row-reverse"
        >
          <ListModal />
        </Grid>
        <Grid container item lg={12} direction="row" spacing={1}>
          {TodoListList.map((l: ListItem, index: number) => (
            <Grid key={index} item lg={3} sm={6} xs={12}>
              <SingleList title={l.title || ""} tasks={l.tasks} />
            </Grid>
          ))}
        </Grid>
      </Grid>
    </>
  );
};

function mapDispatchToProps(dispatch: any) {
  return bindActionCreators(
    {
      ...Actions,
    },
    dispatch
  );
}

function mapStateToProps(state: any) {
  console.log("state inside lists component, bottom:", state);
  console.log("TodoListList, bottom:", state.todoList?.List);

  return {
    TodoListList: state.todoList?.state || [],
  };
}
export default connect(mapStateToProps, mapDispatchToProps)(Lists);

Solution

  • In your example, the function to fetch data and the data list are passed in props.So you don't need to use useState.

    You should use useState if api call is made in Lists component.