I want to build a CRUD App with React Hooks and the Context API. my problem is in the EditUser component. when I click on edit button to edit user it doesn't show anything on the page and in the console I have this error:
selectedUser is undefined for this part value={selectedUser.name} name="name"
<Input type='text' palaceholder="Enter Name"
value={selectedUser.name} name="name"
onChange={(e) => handleOnChange("name", e.target.value)}
></Input>
thank you for your help!
Here is my components:
GlobalState component:
import React, { createContext, useReducer } from 'react'
import AppReducer from './AppReducer'
//Initial State
const initialState = {
users: [
]
}
//Create Context
export const GlobalContext = createContext(initialState);
//Provider Component
export const GlobalProvider = ({ children }) => {
const [state, dispatch] = useReducer(AppReducer, initialState);
//Actions
const removeUser = (id) => {
dispatch({
type: 'REMOVE_USER',
payload: id
})
}
const addUser = (user) => {
dispatch({
type: 'ADD_USER',
payload: user
})
}
const editUser = (user) => {
dispatch({
type: 'EDIT_USER',
payload: user
})
}
return (
<GlobalContext.Provider value={{ users: state.users, removeUser, addUser, editUser }}>
{children}
</GlobalContext.Provider>
)
}
AppReducer component:
export default (state, action) => {
switch (action.type) {
case 'REMOVE_USER':
return {
users: state.users.filter(user => {
return user.id !== action.payload
})
}
case 'ADD_USER':
return {
users: [action.payload, ...state.users]
}
case 'EDIT_USER':
const updateUser = action.payload;
const editUsers = state.users.map(user => {
if (user.id === updateUser.id) {
return updateUser
}
return user
});
return {
users: editUsers
}
default:
return state
}
}
and finallyEditUsercomponent:
import { Link, useNavigate, useParams } from 'react-router-dom';
import { GlobalContext } from '../context/GlobalState';
import React,{ useContext, useState, useEffect } from 'react';
import {
Form,
FormGroup,
Label,
Input,
Button
} from 'reactstrap'
const EditUser = () => {
const [selectedUser, setSelectedUser] = useState({
id: "",
name:""
})
const { users, editUser } = useContext(GlobalContext)
const navigate = useNavigate()
const { currentUserId } = useParams();
useEffect(() => {
const userId = currentUserId;
const selectedUser = users.find(user => user.id === parseInt(userId));
setSelectedUser(selectedUser);
}, [currentUserId, users])
const handleSubmit = (e) => {
e.preventDefault();
editUser(selectedUser);
navigate('/');
};
const handleOnChange = (userKey, newValue) => {
setSelectedUser({ ...selectedUser, [userKey]: newValue })
};
return (
<Form onSubmit={handleSubmit}>
<FormGroup>
<Label>Name</Label>
<Input type='text' palaceholder="Enter Name"
value={selectedUser.name} name="name"
onChange={(e) => handleOnChange("name", e.target.value)}
></Input>
</FormGroup>
<Button type='submit' className='bg-success '>Edit Name</Button>
<Link to="/" className="btn btn-danger m-2">Cancel</Link>
</Form>
);
}
export default EditUser;