当 ReactJS 中不同.js文件的组件中发生状态更改时,如何更新我的 useEffect 钩子?



我正在尝试在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文件,我不确定如何使我的逻辑如上所述在这种情况下工作

ManageUsers.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>
);
}

AddUserButton.js

export default function AddDeviceButton() {
...
return (
<div>
<Button variant="contained" onClick={handleClickOpen}>
Add a device
</Button>
...
</div>
);
} 

一种常见的方法是向按钮组件传递一个回调函数,用于更新父组件的状态。

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>
);
}

因此,您似乎正在尝试让子级更新其父级的状态,一种简单的方法是让父级为子级提供回调,该回调将在调用时更新父级的州。

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}/>);
}

如果在AddUser事件触发后立即通知ManageUsers组件从后端获取,那么几乎肯定不会在响应中看到最新的用户。

为什么后端接收新用户请求需要一段时间,传递适当的安全规则需要更长的时间,格式化、消毒和放置在DB中需要更长的时间,API从中获取更新需要更长的一段时间。

我们能做什么如果您管理状态中的用户(看起来像是基于setUsers(response.data)(,那么您可以将新用户直接添加到状态变量中,这样用户就会立即出现在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>
}
</>
);
}

一旦用户添加了一个新用户;提交";按钮,它将新用户传递给"用户";添加";作为道具流传下来的功能。然后,用户被附加到ManageUsers组件的users数组中,从而立即在UserList组件中填充最新的用户数据。如果我们等待新的获取请求通过,这将增加延迟,并且我们刚刚添加的最新用户不太可能返回响应。

最新更新