[英]React: How to update parent component's useEffect hook when using routes
[英]How to update my useEffect hook when State change happen in a different .js file's component in ReactJS?
我正在尝试在 useEffect() 中进行 API 调用,并希望每次在后端添加新数据时调用 useEffect()。 我制作了一个自定义按钮(AddUserButton.js),它在后端添加了一个新用户。 我正在尝试显示所有用户的文件 (ManageUsers.js) 中导入此按钮。 我只是想制作一个 useState 以在每次单击添加按钮时进行跟踪,并根据它进行 useEffect 刷新。 例如:
const [counter, setCounter] = useState(0);
...
const handleAdd = () => {
setCounter(state => (state+1));
};
...
useEffect(() => {
// fetch data here
...
}, [counter]);
...
return(
<Button onClick = {handleAdd}> Add User </Button>
);
但目前因为我有两个 .js 文件,所以我不确定在这种情况下如何使我的上述逻辑起作用
管理用户.js
import AddUserButton from "./AddUserButton";
...
export default function ManageShades() {
...
useEffect(() => {
axios
.get("/api/v1/users")
.then(function (response) {
// After a successful add, store the returned devices
setUsers(response.data);
setGetUserFailed(false);
})
.catch(function (error) {
// After a failed add
console.log(error);
setGetUserFailed(true);
});
console.log("Load User useeffect call")
},[]);
return (
<div>
...
<Grid item xs={1}>
<AddUserButton title = "Add User" />
</Grid>
...
</div>
);
}
添加用户按钮.js
export default function AddDeviceButton() {
...
return (
<div>
<Button variant="contained" onClick={handleClickOpen}>
Add a device
</Button>
...
</div>
);
}
一种常见的方法是将回调 function 传递给更新父组件的 state 的按钮组件。
import { useState, useEffect } from "react";
const AddUserButton = ({ onClick }) => {
return <button onClick={onClick} />;
};
export default function Test() {
const [updateCount, setUpdateCount] = useState(false);
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count++);
}, [updateCount]);
return (
<div>
<AddUserButton
onClick={() => {
// do something, e.g. send data to your API
// finally, trigger update
setUpdateCount(!updateCount);
}}
/>
</div>
);
}
因此,您似乎正在尝试让孩子更新其父母的 state,一种简单的方法是让父母为孩子提供回调,这将在调用时更新父母的 state。
const parent = ()=>{
const [count, setCount] = useState(0);
const increCallback = ()=>{setCount(count + 1)};
return (<div>
<child callback={increCallback}/>
</div>);
}
const child = (callback)=>{
return (<button onClick={callback}/>);
}
如果您要告诉 ManageUsers 组件在触发 AddUser 事件后立即从后端获取数据,您几乎肯定不会在响应中看到最新的用户。
为什么? 后端接收新用户请求需要一些时间,通过适当的安全规则需要一些时间,格式化、清理和放入数据库需要一些时间,还有一点时间该更新可用于 API 的时间更长。
我们可以做什么? 如果您根据setUsers(response.data)
管理 state 中的用户——这看起来像您所做的——那么您可以将新用户直接添加到 state 变量,然后该用户将立即出现在 UI 中。 然后在后台将新的用户数据异步添加到后端。
我们该怎么做? 这是一个非常简单的流程,看起来像这样(大致基于您现在拥有的组件结构)
function ManageUsers() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('https://api.com')
.then(res => res.json())
.then(res => setUsers(res));
.catch(err => console.error(err));
}, [setUsers]);
const handleAdd = ({ name, phone, dob }) => {
const newUser = {
name,
phone,
dob
};
setUsers([...users, newUser]);
};
return (
<div>
<UserList data={users} />
<AddUser add={handleAdd} />
</div>
);
}
// ...
function AddUser({ add }) {
const [userForm, setUserForm] = useState({ name: "", phone: "", dob: "" });
return (
// controlled form fields
<button onClick={() => add(userForm)}>Submit</button>
);
}
// ...
function UserList({ data }) {
return (
<>
{data.map(user =>
<p>{user.name></p>
}
</>
);
}
一旦用户使用“提交”按钮添加新用户,它会将新用户传递给“添加”function,它已作为道具传递。 然后将用户附加到 ManageUsers 组件的users
数组,立即将最新的用户数据填充到 UserList 组件中。 如果我们等待新的获取请求通过,这将增加延迟,并且我们刚刚添加的最新用户不太可能返回响应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.