Home > Back-end >  I try to show my users, but it doesn't work
I try to show my users, but it doesn't work

Time:01-11

I don´t know why my users are undefined in my console.log I can see them in my State but I can´t list them on the page .. It showed up before where I have not yet used Redux .. after using Redux it no longer works that the users are displayed.

I'll show you a piece of the code where it should be displayed and how My UserManagement.js:

function UserManagement({ history }) {
 
  const dispatch = useDispatch();
  
  const userLogin = useSelector((state) => state.userLogin);
  const userList = useSelector((state) => state.userList);
  const { loading  } = userLogin;
  const { users} = userList;

 
  useEffect(() => {
    dispatch(getUsers());
  },[dispatch, history]);

  const deleteHandler = (id) => {
    if (window.confirm("Are you sure? you want to delete")) {
      dispatch(deleteUserAction(id));
    }
  };

  
  console.log(userList);
  console.log(users);
  return (
    <MainScreen title={`List of Users`}>
       <Link to="/createUser" id="OpenCreateUserDialogButton">
        <Button style={{ marginLeft: 10, marginBottom: 6 }} size="lg">
          Create new User
        </Button>
      </Link>
      
      {loading && <Loading />}
     
      {users &&
        users?.map((users) => (
         
          <Accordion>
            <Card style={{ margin: 10 }} key={users._id}>
              <Card.Header style={{ display: "flex" }}>
                <span
                  // onClick={() => ModelShow(note)}
                  style={{
                    color: "black",
                    textDecoration: "none",
                    flex: 1,
                    cursor: "pointer",
                    alignSelf: "center",
                    fontSize: 18,
                  }}
                >
                      
                      {users.userID}               
                </span>
                <div>
                  <Link to="/profileedit">
                    <Button
                    id="EditButton"
                    >Edit</Button>
                    </Link>
                    <Button
                      id="DeleteButton"
                      variant="danger"
                      className="mx-2"
                      onClick={() => deleteHandler(users.id)}
                    >
                      Delete
                    </Button>
                  </div>
              </Card.Header>

I will show my Reducer function:

export const userListReducer = (state = {}, action) => {
    switch (action.type) {
      case USER_LIST_REQUEST:
        return { loading: true };
      case USER_LIST_SUCCESS:
        return { loading: true, userList: action.payload, success: true };
      case USER_LIST_FAIL:
        return { loading: false, error: action.payload, success: false };
      default:
        return state;
    }
  }

And this is my userAction:

  export const getUsers = (user) => async (dispatch, getState) => {
    try {
      dispatch({ type: USER_LIST_REQUEST });
  
      const {
         userLogin: { userInfo },
        } = getState();
      
      const config = {
        headers: {
          Authorization: `Bearer ${userInfo.token.token}`,
        },
      };
      const url = "http://localhost:8080/user/"
      const { data } = await axios.get(url, config);
  
      dispatch({ type: USER_LIST_SUCCESS, payload: data });
  
    
    } catch (error) {
      dispatch({
        type: USER_LIST_FAIL,
        payload:
          error.response && error.response.data.message
            ? error.response.data.message
            : error.message,
      });
    }
  };

CodePudding user response:

Following my comment on your question.

This is how you should be using a state variable.

function UserManagement({ history }) {
 
  const dispatch = useDispatch();
  
  const userList = useSelector((state) => state.userList);
 
  useEffect(() => {
    dispatch(getUsers());
  },[dispatch, history]);

  useEffect(() => {
    console.log(userList);
  },[userList]);

  ...
}

If you still need to create another variable, you need to assign it a value every time userList changes - by adding this line to the useEffect method just like this.

function UserManagement({ history }) {
 
  const dispatch = useDispatch();
  
  const userList = useSelector((state) => state.userList);
  let users = userList;
 
  useEffect(() => {
    dispatch(getUsers());
  },[dispatch, history]);

  useEffect(() => {
    users = userList;
  },[userList]);

  ...
}

Notice that when you assign a value to a variable like this:

The value assigned to that variable is the initial value of the assigned variable (undefined) because the reducer has not yet updated the state value. And when it actually updates it, nothing updates the second variable you created "users"

  const userList = useSelector((state) => state.userList);
  const users = userList;

And you can use it to manipulate your UI by:

{userList &&
    userList.map((users) => (
        <MyComponent/>
    )
}

CodePudding user response:

I added a comment to this question,so check that too.

However I just noticed something else that should help you.

Due the the way state works your users are probably returning as undefined

You have two choices here.

  1. Change your users.map() to userList.users.map() as userList.

  2. If you really want it to just be users.map() then you might have to use some react state. For example

import { useSelector } from 'react-redux';
import { useEffect, useState } from 'react'; 
import { MyUserComponent } from 'some_file';

const YourComponent = () => {
  // grab your userList from redux
  const userList = useSelector(state => state.userList);
  
  // create some state for use the users
  // an empty array to start
  const [users, setUsers] = useState([]);
  
  // watch the userList for changes
  useEffect(() => {
    // update the users state whenever 
    // there is a change to useList
    setUsers(userlist.users)
    
  }, [userList])
  
  
  // do whatever you want in your return
  return (
    <div>
      { 
        users.map(user => <MyUserComponent {...user} key={`user-${index}`}) />
      }
    </div>
  )
}

Honestly I'd just do option 1

  •  Tags:  
  • Related