简体   繁体   English

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

[英]How to update my useEffect hook when State change happen in a different .js file's component in ReactJS?

I am trying to make an API call in useEffect() and want useEffect() to be called everytime a new data is added in the backend.我正在尝试在 useEffect() 中进行 API 调用,并希望每次在后端添加新数据时调用 useEffect()。 I made a custom Button(AddUserButton.js) which adds a new user in backend.我制作了一个自定义按钮(AddUserButton.js),它在后端添加了一个新用户。 I am importing this button in the file (ManageUsers.js) where I am trying to display all the users.我正在尝试显示所有用户的文件 (ManageUsers.js) 中导入此按钮。 I just wanted to make an useState to keep track everytime an add button is clicked and make useEffect refresh according to it.我只是想制作一个 useState 以在每次单击添加按钮时进行跟踪,并根据它进行 useEffect 刷新。 For Example:例如:

const [counter, setCounter] = useState(0);
...
const handleAdd = () => {
  setCounter(state => (state+1));
};
...
useEffect(() => {
 // fetch data here
 ...
}, [counter]);
...
return(
 <Button onClick = {handleAdd}> Add User </Button>

);

But currently because I have two.js files, I am not sure how to make my logic stated above work in this case但目前因为我有两个 .js 文件,所以我不确定在这种情况下如何使我的上述逻辑起作用

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

AddUserButton.js添加用户按钮.js

export default function AddDeviceButton() {
...

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

A common approach is to pass a callback function to your button component that updates the state of the parent component.一种常见的方法是将回调 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>
  );
}

So it seems like you are trying to let a child update it's parent's state, an easy way to do this is to let the parent provide the child a callback, which will update the parent's state when called.因此,您似乎正在尝试让孩子更新其父母的 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}/>);
}

If you were to tell the ManageUsers component to fetch from the back-end right after the AddUser event is fired, you will almost certainly not see the latest user in the response.如果您要告诉 ManageUsers 组件在触发 AddUser 事件后立即从后端获取数据,您几乎肯定不会在响应中看到最新的用户。

Why?为什么? It will take some time for the new user request to be received by the back-end, a little longer for proper security rules to be passed, a little longer for it to be formatted, sanitized, and placed in the DB, and a little longer for that update to be available for the API to pull from.后端接收新用户请求需要一些时间,通过适当的安全规则需要一些时间,格式化、清理和放入数据库需要一些时间,还有一点时间该更新可用于 API 的时间更长。

What can we do?我们可以做什么? If you manage the users in state - which it looks like you do, based on the setUsers(response.data) - then you can add the new user directly to the state variable, which will then have the user appear immediately in the UI.如果您根据setUsers(response.data)管理 state 中的用户——这看起来像您所做的——那么您可以将新用户直接添加到 state 变量,然后该用户将立即出现在 UI 中。 Then the new user data is asynchronously added to the back-end in the background.然后在后台将新的用户数据异步添加到后端。

How can we do it?我们该怎么做? It's a really simple flow that looks something like this (based roughly on the component structure you have right now)这是一个非常简单的流程,看起来像这样(大致基于您现在拥有的组件结构)

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

Once the user adds a new user with the "Submit" button, it passes the new user to the "add" function which has been passed down as a prop.一旦用户使用“提交”按钮添加新用户,它会将新用户传递给“添加”function,它已作为道具传递。 Then the user is appended to the users array of the ManageUsers component, instantly populating the latest user data in the UserList component.然后将用户附加到 ManageUsers 组件的users数组,立即将最新的用户数据填充到 UserList 组件中。 If we wait for a new fetch request to come through, this will add a delay, and the newest user we just added will not likely come back with the response.如果我们等待新的获取请求通过,这将增加延迟,并且我们刚刚添加的最新用户不太可能返回响应。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React:如何在使用路由时更新父组件的useEffect hook - React: How to update parent component's useEffect hook when using routes 如何在 useEffect 挂钩中正确地对 reactjs state object 属性进行功能更新 - How to make functional update of reactjs state object property correctly inside useEffect hook 当我的状态在ReactJS中更改状态时重新渲染组件 - rerender component when my state change state in ReactJS Reactjs如何从不同的组件更改组件的状态 - Reactjs how to change the state of a component from a different component 如何从Reactjs中的子组件更新父组件的状态 - How to update a parent's component state from a child component in Reactjs 无法使用 useEffect 挂钩对未安装的组件执行 React state 更新 - Can't perform a React state update on an unmounted component with useEffect hook useContext 未在子组件中显示更新的状态(当从全局文件中 useEffect 钩子中的 firebase 检索数据时) - useContext is not displaying the updated state (when data is retrieved from firebase in useEffect hook in global file) in child component useEffect 钩子怎么可能改变 state,条件是改变相同的 state? - How is it possible that the useEffect hook changes a state conditional on the change of the same state? 为什么我的组件在使用 React 的 Context API 和 useEffect 钩子时渲染了两次? - Why does my component render twice when using React's Context API and the useEffect hook? state 值在使用 useEffect 挂钩时不会改变 - state value does not change when using useEffect hook
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM