编辑功能不适用于我的 CRUD 应用程序
Edit function not working for my CRUD App
我正在构建一个简单的 CRUD 应用程序,我有 90% 的工作正常,但由于某种原因我无法使用“编辑”功能。当我去编辑我的团队成员姓名时,单击“编辑姓名”时没有任何反应。值得注意的是,我从我的“添加用户”组件中复制了代码并进行了修改。这是我的代码:
// 编辑用户
import React, { useState, useContext, useEffect } from 'react'
import { GlobalContext } from '../context/GlobalState'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { Form, FormGroup, Label, Input, Button } from 'reactstrap'
const EditUser = (props) => {
const [selectedUser, setSelectedUser] = useState({
id: '',
name: ''
});
const { users, editUser } = useContext(GlobalContext);
const navigate = useNavigate();
const currentUserId = useParams(props);
useEffect(() => {
const userId = currentUserId;
const selectedUser = users.find((user) => user.id === userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [currentUserId, users]);
const onSubmit = (e) => {
e.preventDefault()
editUser(selectedUser)
navigate('/');
}
const onChange = (e) => {
setSelectedUser({...selectedUser, [e.target.name]: e.target.value})
}
return (
<div className='container w-25'>
<Form className='form-control' onSubmit={onSubmit}>
<FormGroup>
<Label>Edit Name</Label>
<Input type='text' name='name' value={selectedUser.name} onChange={onChange} placeholder='Enter Name'></Input>
</FormGroup>
<Button type='submit'>Edit Name</Button>
<Link to='/' className='btn btn-danger m-2'>Back</Link>
</Form>
</div>
)
}
export default EditUser
// 添加用户
import React, { useState, useContext } from 'react'
import { GlobalContext } from '../context/GlobalState'
import { Link, useNavigate } from 'react-router-dom'
import { v4 as uuid } from 'uuid';
import { Form, FormGroup, Label, Input, Button } from 'reactstrap'
const AddUser = () => {
const [name, setName] = useState('');
const { addUser } = useContext(GlobalContext);
const navigate = useNavigate();
const onSubmit = (e) => {
e.preventDefault()
const newUser = {
id: uuid(),
name: name
}
addUser(newUser);
navigate('/');
}
const onChange = (e) => {
setName(e.target.value);
}
return (
<div className='container w-25'>
<Form className='form-control' onSubmit={onSubmit}>
<FormGroup>
<Label>Name</Label>
<Input
type='text'
name={name}
value={name}
onChange={onChange}
placeholder='Enter Name'></Input>
</FormGroup>
<Button type='submit'>Submit</Button>
<Link to='/' className='btn btn-danger m-2'>Back</Link>
</Form>
</div>
)
}
export default AddUser
// 全局上下文
import React, { createContext, useReducer } from 'react';
import AppReducer from './AppReducer';
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>
)
}
// 应用减速器
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 updateUsers = state.users.map(user => {
if(user.id === updateUser.id) {
return updateUser;
}
return user;
})
return {
users: updateUsers
}
default:
return state
}
}
问题
问题似乎是 Edit
组件没有正确访问路由路径参数对象,以引用路由路径的 userId
参数。
const currentUserId = useParams();
useEffect(() => {
const userId = currentUserId;
const selectedUser = users.find((user) => user.id === userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [currentUserId, users]);
这里整个params对象被命名为currentUserId
。在 useEffect
挂钩回调中,此参数对象被分配给局部变量 userId
,然后用于在 users
数组中查找匹配的用户对象。它将特定用户的 id
属性(字符串类型)与整个参数对象(对象类型)进行比较.此 OFC 永远不会相等并且 selectedUser
未定义并且本地 selectedUser
状态永远不会初始化为您尝试编辑的用户。
解决方案
访问params对象以正确访问特定参数:
const currentUserId = useParams();
useEffect(() => {
const userId = currentUserId;
const selectedUser = users.find((user) => user.id === userId.userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [currentUserId, users]);
或者直接解构userId
路径参数:
const { userId } = useParams();
useEffect(() => {
const selectedUser = users.find((user) => user.id === userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [userId, users]);
建议
直接初始化selectedUser
状态。使用 useEffect
挂钩检查是否有用户要编辑,如果没有用户要编辑则返回导航。
const EditUser = () => {
const navigate = useNavigate();
const { userId } = useParams();
const { users, editUser } = useGlobalContext(); // *
const [selectedUser, setSelectedUser] = useState(
users.find((user) => user.id === userId)
);
useEffect(() => {
if (!selectedUser) navigate(-1);
}, [navigate, selectedUser]);
const onSubmit = (e) => {
e.preventDefault();
editUser(selectedUser);
navigate("/");
};
const onChange = (e) => {
setSelectedUser({ ...selectedUser, [e.target.name]: e.target.value });
};
return (
<div className="container w-25">
{selectedUser && (
<Form className="form-control" onSubmit={onSubmit}>
<FormGroup>
<Label>Edit Name</Label>
<Input
type="text"
name="name"
value={selectedUser.name}
onChange={onChange}
placeholder="Enter Name"
/>
</FormGroup>
<Button type="submit">Edit Name</Button>
<Link to="/" className="btn btn-danger m-2">
Back
</Link>
</Form>
)}
</div>
);
};
* 注意:这只是为了方便在上下文代码中创建的自定义挂钩:
const useGlobalContext = () => useContext(GlobalContext);
我正在构建一个简单的 CRUD 应用程序,我有 90% 的工作正常,但由于某种原因我无法使用“编辑”功能。当我去编辑我的团队成员姓名时,单击“编辑姓名”时没有任何反应。值得注意的是,我从我的“添加用户”组件中复制了代码并进行了修改。这是我的代码:
// 编辑用户
import React, { useState, useContext, useEffect } from 'react'
import { GlobalContext } from '../context/GlobalState'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { Form, FormGroup, Label, Input, Button } from 'reactstrap'
const EditUser = (props) => {
const [selectedUser, setSelectedUser] = useState({
id: '',
name: ''
});
const { users, editUser } = useContext(GlobalContext);
const navigate = useNavigate();
const currentUserId = useParams(props);
useEffect(() => {
const userId = currentUserId;
const selectedUser = users.find((user) => user.id === userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [currentUserId, users]);
const onSubmit = (e) => {
e.preventDefault()
editUser(selectedUser)
navigate('/');
}
const onChange = (e) => {
setSelectedUser({...selectedUser, [e.target.name]: e.target.value})
}
return (
<div className='container w-25'>
<Form className='form-control' onSubmit={onSubmit}>
<FormGroup>
<Label>Edit Name</Label>
<Input type='text' name='name' value={selectedUser.name} onChange={onChange} placeholder='Enter Name'></Input>
</FormGroup>
<Button type='submit'>Edit Name</Button>
<Link to='/' className='btn btn-danger m-2'>Back</Link>
</Form>
</div>
)
}
export default EditUser
// 添加用户
import React, { useState, useContext } from 'react'
import { GlobalContext } from '../context/GlobalState'
import { Link, useNavigate } from 'react-router-dom'
import { v4 as uuid } from 'uuid';
import { Form, FormGroup, Label, Input, Button } from 'reactstrap'
const AddUser = () => {
const [name, setName] = useState('');
const { addUser } = useContext(GlobalContext);
const navigate = useNavigate();
const onSubmit = (e) => {
e.preventDefault()
const newUser = {
id: uuid(),
name: name
}
addUser(newUser);
navigate('/');
}
const onChange = (e) => {
setName(e.target.value);
}
return (
<div className='container w-25'>
<Form className='form-control' onSubmit={onSubmit}>
<FormGroup>
<Label>Name</Label>
<Input
type='text'
name={name}
value={name}
onChange={onChange}
placeholder='Enter Name'></Input>
</FormGroup>
<Button type='submit'>Submit</Button>
<Link to='/' className='btn btn-danger m-2'>Back</Link>
</Form>
</div>
)
}
export default AddUser
// 全局上下文
import React, { createContext, useReducer } from 'react';
import AppReducer from './AppReducer';
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>
)
}
// 应用减速器
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 updateUsers = state.users.map(user => {
if(user.id === updateUser.id) {
return updateUser;
}
return user;
})
return {
users: updateUsers
}
default:
return state
}
}
问题
问题似乎是 Edit
组件没有正确访问路由路径参数对象,以引用路由路径的 userId
参数。
const currentUserId = useParams();
useEffect(() => {
const userId = currentUserId;
const selectedUser = users.find((user) => user.id === userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [currentUserId, users]);
这里整个params对象被命名为currentUserId
。在 useEffect
挂钩回调中,此参数对象被分配给局部变量 userId
,然后用于在 users
数组中查找匹配的用户对象。它将特定用户的 id
属性(字符串类型)与整个参数对象(对象类型)进行比较.此 OFC 永远不会相等并且 selectedUser
未定义并且本地 selectedUser
状态永远不会初始化为您尝试编辑的用户。
解决方案
访问params对象以正确访问特定参数:
const currentUserId = useParams();
useEffect(() => {
const userId = currentUserId;
const selectedUser = users.find((user) => user.id === userId.userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [currentUserId, users]);
或者直接解构userId
路径参数:
const { userId } = useParams();
useEffect(() => {
const selectedUser = users.find((user) => user.id === userId);
if (selectedUser) {
setSelectedUser(selectedUser);
}
}, [userId, users]);
建议
直接初始化selectedUser
状态。使用 useEffect
挂钩检查是否有用户要编辑,如果没有用户要编辑则返回导航。
const EditUser = () => {
const navigate = useNavigate();
const { userId } = useParams();
const { users, editUser } = useGlobalContext(); // *
const [selectedUser, setSelectedUser] = useState(
users.find((user) => user.id === userId)
);
useEffect(() => {
if (!selectedUser) navigate(-1);
}, [navigate, selectedUser]);
const onSubmit = (e) => {
e.preventDefault();
editUser(selectedUser);
navigate("/");
};
const onChange = (e) => {
setSelectedUser({ ...selectedUser, [e.target.name]: e.target.value });
};
return (
<div className="container w-25">
{selectedUser && (
<Form className="form-control" onSubmit={onSubmit}>
<FormGroup>
<Label>Edit Name</Label>
<Input
type="text"
name="name"
value={selectedUser.name}
onChange={onChange}
placeholder="Enter Name"
/>
</FormGroup>
<Button type="submit">Edit Name</Button>
<Link to="/" className="btn btn-danger m-2">
Back
</Link>
</Form>
)}
</div>
);
};
* 注意:这只是为了方便在上下文代码中创建的自定义挂钩:
const useGlobalContext = () => useContext(GlobalContext);