【问题标题】:React state is empty inside useEffect反应状态在 useEffect 中为空
【发布时间】:2021-07-20 00:41:28
【问题描述】:

目前我正在构建一个带有反应的推送聊天应用程序。我正在尝试保留在线用户列表。我在下面使用这个代码:

const [users, setUsers] = useState([]);
useEffect(() => { // UseEffect so only called at first time render
window.Echo.join("server.0")
  .here((allUsers) => {
    let addUsers = [];
    allUsers.map((u) => {
      addUsers.push(u.name)
    })
    setUsers(addUsers);
  })
  .joining((user) => {
    console.log(`User ${user.name} joined`);
    setUsers([users, user]);
  })
  .leaving((user) => {
    console.log(`User ${user.name} left`);
    let addUsers = users;
    addUsers.filter((u) => {
      return u !== user.name;
    })
    setUsers(addUsers);
  })}, []);

每当我订阅推送频道时,我都会收到当前订阅的用户并且状态设置正确。所有订阅的用户都在显示。但是,当新用户加入/离开时,将调用 .joining/.leaving 方法,并且当我控制台登录时用户状态为空。这样,用户状态被设置为仅新添加的用户,而所有其他用户都被忽略。我是新手,所以对此可能有一个简单的解释。我自己很难找到答案。非常感谢您的帮助。

【问题讨论】:

    标签: reactjs laravel pusher laravel-echo


    【解决方案1】:

    我在joining 中看到了问题。您需要像这样更新 setState:setUsers([...users, user.name]);

    leaving也需要更新:

    const addUsers = users.filter((u) => {
      return u !== user.name;
    });
    setUsers(addUsers);
    

    here 也应该重写:

    let addUsers = allUsers.map((u) => u.name);
    setUsers(addUsers);
    

    【讨论】:

    • 我试过这个,但不幸的是仍然面临同样的问题。每当有新用户加入时,用户状态都会更新为仅包含新订阅用户的数组。每当我尝试从 useEffect 方法中访问用户状态时,它似乎都是空的。
    【解决方案2】:

    我发现了问题。问题是当从回调函数中访问状态时,它总是返回初始值。在我的情况下,一个空数组。它在使用引用变量时确实有效。我添加了以下几行:

      const [users, _setUsers] = useState([]);
      const usersRef = React.useRef(users);
      const setUsers = data => {
       usersRef.current = data;
      _setUsers(data);
       }
    

    每次更新用户状态时,我都会使用 setUsers 函数。现在,当我使用 usersRef.current 从回调函数内部访问状态时,我得到了最新状态。

    我还使用@Viet 答案中的代码来正确更新值。

    【讨论】:

      猜你喜欢
      • 2021-02-23
      • 2020-07-08
      • 1970-01-01
      • 2021-09-07
      • 2017-06-23
      • 2019-06-21
      • 1970-01-01
      • 2023-02-16
      • 2020-07-10
      相关资源
      最近更新 更多