React 不渲染对象中的更新

问题描述 投票:0回答:2

我已经使用了 React 组件,如果我控制对象,它会在其中显示对象键值。但是如果我在组件中访问它

undefined
.

我已经像这样初始化了对象,

let faeko = new Faeko({}, client)

用户登录后,

faeko
对象更新为
occupants
。它显示在控制台中,因为 Javascript 在记录值中的实时更新。

我使用 useEffect 和 setTimeout 来添加延迟以更新组件中的值。但它不是。

这是我的

GameFrame.jsx
。它记录了居住者的价值。如果它显示出来,那么它应该在 DOM 中渲染居住者。但它不是。

import React, { useEffect, useState } from "react";

export const GameFrame = (props) => {
  console.log("TEST FAEKO ", props.game.data);
  const [start, setStart] = useState({});
 
  let timer;

  useEffect(() => {
    console.log("tested", props.game);
    console.log("Props.game", props.game.data);

    clearTimeout(timer);

    timer = setTimeout(() => {
      console.log("props gets updated!", props.game.data.occupants);
      setStart(props.game.data);
    }, 1000);
  }, [props.game.data]);

  return (
    <div>
      {/* {console.log("start ", start)} */}
      {start.occupants !== undefined && start.occupants.length > 0 && (
        // console.log("here updated", start.occupants) &&
        <div>Occupants</div>
      )}
    </div>
  );
};

我该怎么办,它在单个选项卡中工作。如果我需要在我创建的房间中加入第二个用户,它不会呈现。可以解决吗?

如果你想参加谷歌会议,请问我! 我在这浪费了5天……

javascript reactjs react-hooks hook
2个回答
0
投票

根据您的代码和描述,问题似乎与

props.game
对象更新的异步性质有关。当您在
props.game.data
挂钩中记录
useEffect
时,您可能会看到更新后的值,因为它会在更新后立即记录该值。但是,当您尝试在 return 语句中访问依赖于
props.game.data
的起始状态变量时,它可能仍然具有初始值,因为状态更新可能尚未发生。

解决此问题的一种方法是在返回语句中添加条件检查,以便仅在开始状态变量已使用新的

props.game.data
值更新时才呈现组件。

带有此检查的代码的更新版本:

import React, { useEffect, useState } from "react";

export const GameFrame = (props) => {
  console.log("TEST FAEKO ", props.game.data);
  const [start, setStart] = useState({});
 
  useEffect(() => {
    console.log("tested", props.game);
    console.log("Props.game", props.game.data);

    const timer = setTimeout(() => {
      console.log("props gets updated!", props.game.data.occupants);
      setStart(props.game.data);
    }, 1000);

    return () => clearTimeout(timer); // clear the timeout on component unmount
  }, [props.game.data]);

  if (!Object.keys(start).length) { // check if start object is empty
    return null; // return null until it gets updated
  }

  return (
    <div>
      {start.occupants && start.occupants.length > 0 && (
        <div>Occupants</div>
      )}
    </div>
  );
};

这段代码中,return语句中的if语句检查起始对象是否不为空。如果为空,则返回 null 以不呈现任何内容。一旦起始对象更新为新的

props.game.data
值,组件将使用更新后的值重新渲染。

另请注意,我将定时器声明移到了

useEffect
钩子中以避免多个定时器同时运行的潜在问题,并添加了一个清除函数以清除组件卸载时的超时。


0
投票

看起来您正在尝试使用 props.game.data 更改 gamestate 组件,但是如果 props.game.data 对象在 GameFrame 之外更新,则对象作为参考传递,它不会重新渲染,所以这就是我建议使用的原因useeffect 以便您可以将唯一标识符作为道具传递给 GameFrame 组件

import React, { useEffect, useState } from "react";

export const GameFrame = (props) => {
  console.log("TEST FAEKO ", props.game.data);
  const [start, setStart] = useState({});
 
  let timer;

  useEffect(() => {
    console.log("tested", props.game);
    console.log("Props.game", props.game.data);

    clearTimeout(timer);

    timer = setTimeout(() => {
      console.log("props gets updated!", props.game.data.occupants);
      setStart(props.game.data);
    }, 1000);
  }, [props.identifier]);

  return (
    <div>
      {/* {console.log("start ", start)} */}
      {start.occupants !== undefined && start.occupants.length > 0 && (
        // console.log("here updated", start.occupants) &&
        <div>Occupants</div>
      )}
    </div>
  );
};
<GameFrame game={game} identifier={game.data.occupants.length} />

我建议将这个识别道具用于游戏框架

© www.soinside.com 2019 - 2024. All rights reserved.