简体   繁体   中英

How to change th value of a state property?

I am making a small application that obtains data, is displayed in the DOM, and chooses an item that displays the information of the chosen user, I handle all this through the state manager called UserState, where I also add the methods to display the users. And then as a component, I have UserList and UserProfile.

This is how should work, Capture 1

捕获1

UserState.js

import React, {useState} from 'react';
import UserContext from './UserContext';
import axios from 'axios';

function UserState(props) {
const initialState = {
    users:[],
    selectedUser:null
}

const [state, setState] = useState(initialState) 

const getUsers = async() =>{
    const res = await axios.get("https://reqres.in/api/users")
    const data = res.data.data
    setState({users:data,
    selectedUser:null})
}

const getProfile = async (id) => {
    const res = await axios.get("https://reqres.in/api/users/"+id)
    const {data} = await res.data;
    console.log('Item Selected:',data)
    console.log(setState({selectedUser:data}))

}

return (
    <UserContext.Provider
        value={{
            users:state.users,
            selectedUser: state.selectedUser,
            getUsers,
            getProfile
            }}
    >
        {props.children}
    </UserContext.Provider>
)
}

export default UserState

I export That state and its methods through the Hook useContext, the problem starts when I try to choose a user, and the console shows me the following error.

UserList.js

import React,{useContext,useEffect} from 'react'
import UserContext from "../context/User/UserContext"

function UserList(props) {
const  userContext = useContext(UserContext)

useEffect(() => {
     userContext.getUsers();
},[])

return (
    <div>
        <h1>UserList</h1>
        {userContext.users.map(user=>{
            return(
            <a 
                key={user.id}
                href="#!"
                onClick={()=> userContext.getProfile(user.id)}
            >
                <img src={user.avatar} alt="" width="70"/>
                <p>{user.first_name} {user.last_name}</p>
                <p>{user.email}</p>
            </a>)
        }): null}
    </div>
)
}

export default UserList

Profile.js

import React,{useContext} from 'react'
import UserContext from '../context/User/UserContext'

function Profile() {
const {selectedUser} = useContext(UserContext)

return (
    <>
    <h1>Profile</h1>
    {selectedUser ? 
    (
    <div>
        <h1>Selected Profile</h1>
        {/* <img 
            src={selectedUser.avatar}
            alt=""
            style={{width:150}}
        /> */}
    </div>
    ):(<div>
        No User Selected
    </div>)}
    </>
)
}

export default Profile

Console Error

控制台错误

I tried to change the value of selectedUser but every time the console shows me that error.

In your getProfile function, you should use setState like that.

setState({...state, selectedUser:data })

If you use setState({selectedUser:data }) then users is removed from state.

It looks like it's an issue with the asynchronous portion of your code. Initially, you have no state.users object, so when you attempt to use the properties of the state.users object in the line like {userContext.users.map(user=>{... there is nothing to map, and since map uses the length property, you are getting that error. You should check first to see if that component has a userContext.users property and that the length is greater than or equal to 1 before attempting to map.

You're using the useState hook in a slightly odd way too, which confuses things a bit. Typically when using the useState hook, each element will have its own state rather than setting a single state to handle multiple elements. In this one, you'd set two separate states, one called users and one called selectedUser and set them independently. Otherwise you can have some odd re-renders.

By the way, React error codes are very descriptive. It tells you that state.users is undefined, that it can't access property map of undefined, and that it's on line 13 of your UserList.js component. All of which is true.

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