javascript - 如何从不是父或子的另一个组件更改功能组件的状态?
问题描述
在我的代码中,我有一个功能组件,它使用“加载更多”分页来呈现数据库中的用户列表,当您单击它们时,一个显示用户详细信息以及一些操作的组件是列表,类似于文件浏览器。其中一项操作是删除用户。当您这样做时,用户列表不会更新,如果您单击刚刚删除的用户,则会出现执行错误,因为代码尝试使用来自空对象的信息。在不使用类组件的情况下在用户删除时更新列表组件的最佳方法是什么?
App.js - 列表和细节组件的父级
<BrowserRouter>
<div id = "app">
<div className = "section sectionTop">
<Route path = "/" component = {BaseTop}/>
</div>
<div className = "Main">
<div className = "section sectionMain sectionLeft">
<Route path = "/" component = {BaseLeft}/>
</div>
<div className = "section sectionMain sectionCenter">
<Route path = "/" exact component = {BaseCenter}/>
<Route path = "/listusers" component = {UserList}/>
</div>
<div className = "section sectionMain sectionRight">
<Route path = "/" exact component = {BaseRight}/>
<Route path = "/adduser" component = {UserAdd}/>
<Route path = "/listusers/:id" component = {UserInfo}/>
</div>
</div>
</div>
</BrowserRouter>
UserList.js - 用户列表
const [users, setUsers] = useState ([]);
const [page, setPage] = useState (0);
useEffect
(
() =>
{
setPage (page+1);
},
[]
);
useEffect
(
() =>
{
try
{
const runEffect = async () =>
{
const response = await api.get
(
`/users?page=${page}`
);
setUsers ([...users, ...response.data.docs]);
}
runEffect();
}
catch (error)
{
console.log (error);
}
},
[page]
);
return (
<div className = "userListArea">
{
users.map
(
(user, index) =>
{
return (
<div key = {index} className = "user">
<Link key = {index} to = {`/listusers/${user._id}`}>
<button
className = "buttonUser"
key = {index}>
{user.name}
</button>
</Link>
</div>
)
}
)
}
<button
className = "buttonLoadMore"
onClick = {() => setPage (page+1)}>
Carregar mais
</button>
</div>
)
UserInfo.js - 用户的详细信息
const [user, setUser] = useState ({});
const [_id, set_id] = useState ("");
useEffect
(
() =>
{
if (user.hasOwnProperty ("_id") === false)
{
set_id (match.params.id);
}
else
{
if (user._id !== match.params.id)
{
set_id (match.params.id);
}
}
const runEffect = async () =>
{
const response = await api.get
(
"/searchuser",
{
params:
{
_id
}
}
)
if (user.hasOwnProperty ("name") === false)
{
setUser (response.data);
}
else
{
if (user.name !== response.data.name)
{
setUser (response.data);
}
}
}
runEffect();
}
);
async function handleDeleteUser (_id)
{
if (window.confirm(`Você realmente deseja remover o usuário ${user.name}?`))
{
const response = await api.delete
(
"/users",
{
params:
{
_id
}
}
);
if (response.data._id === _id)
{
window.alert(`O usuário ${user.name} foi excluído.`);
}
}
}
return (
<div className = "userInfoArea">
<div className = "name">{user.name}</div>
<div className = "email">{user.email}</div>
<button className = "buttonEdit">Editar</button>
<Link to = "/listusers">
<button
className = "buttonDelete"
onClick = {() => handleDeleteUser (user._id)}
>
Excluir
</button>
</Link>
</div>
)
解决方案
如果不使用外部状态管理解决方案(例如Redux或新的useContext api/hook ),则无法更新不是父级或子级的组件的状态。这些库涉及将所有单个组件的状态移动到更大的集中式全局状态,所有组件都可以对其进行更新和访问。
推荐阅读
- javascript - 反应:尝试从音频元素创建媒体元素源时出现 InvalidStateError
- json - Laravel 在 Json 对象数组中搜索日期大于今天的列
- android - 在 webview 中处理 volley HTML 响应
- python - 比较两个列表之间相同索引处的项目并将最小值附加到第三个列表?
- java - 使用java在android studio中显示pdf文件,来自谷歌驱动器链接?
- php - PHP根据搜索检索关联数组的所有键
- python - TypeError:“ID3TimeStamp”类型的对象没有 len()
- c# - Unity:碰撞后改变 RigidBody2D 的速度会导致游戏崩溃,无论平台如何,包括在编辑器中
- google-apps-script - 如何获取 Mimetype 文件 ID
- sql - 查找名为 SQL_ID 的 PL/SQL 包