我有一个 react native 应用程序,我从Firebase Firestore数据库中获取用户.这可以正常工作. 但是,当我试图从User对象获取关注者长度时,它不会显示或更改,只有在我更改代码和应用程序刷新时才会更改.

我在某个地方读到,useEffect在第二个帧上运行,所以我try 将代码放在useEffect之外,但没有任何变化


const [followingLength, setFollowingLength] = useState(0);
const [followersLength, setFollowersLength] = useState(0);

useEffect(() => {
  const userSub = onSnapshot(doc(firestore, "Users", userId), (doc) => {
            setUser(doc.data())

            if (user.following.length !== 0) {
                setFollowingLength(user.following.length)
            }

            if (user.followers.length !== 0) {
                setFollowersLength(user.followers.length)
            }
        });
});

<Text style={{ color: colors.white }}>{followingLength}</Text>
<Text style={{ color: colors.white }}>{followersLength}</Text>

推荐答案

从我明确看到的事情来看:

问题1:为什么你的useEffect没有任何dependency array?在这种情况下,代码将在每个渲染中执行,这将是错误和昂贵的.

问题2:你知道吗,setUser不会立即更新user对象,而if中的user是"旧的"并捕获闭包?

问题3:您知道onSnapshot返回unsubscribe函数,需要调用该函数才能停止监听程序.在您的例子中,每次渲染都要添加1个额外的侦听器,这也有缺陷,而且成本很高.

我不能100%确定这些问题的组合就是你的问题的根源,但它们肯定应该得到解决

注:你可以用useMemo来计算关注和关注.

const [user, setUser] = useState();
const followingLength = useMemo(() => {
  return user?.following?.length || 0;
}, [user]);

const followersLength = useMemo(() => {
  return user?.followers?.length || 0;
}, [user]);

useEffect(() => {
  const unsubscribe = onSnapshot(doc(firestore, "Users", userId), (doc) => {
    setUser(doc.data());

    // Or
    // const u = doc.data();
    // setUser(u);
    // setWhateverElse from "u", not "user"

  });

  return unsubscribe;
}, [userId]);

Javascript相关问答推荐

如何根据当前打开的BottomTab Screeb动态加载React组件?

如何在bslib nav_insert之后更改导航标签的CSS类和样式?

JS—删除对象数组中对象的子对象

变量的值在Reaction组件中的Try-Catch语句之外丢失

当id匹配时对属性值求和并使用JavaScript返回结果

如何在不影响隐式类型的情况下将类型分配给对象?

在开发期间,Web浏览器如何运行&qot;.jsx&qot;文件?

我想使用GAS和HTML将从Electron 表格中获得的信息插入到文本字段的初始值中

如何在下一个js中更改每个标记APEXCHARTS图表的 colored颜色

将Singleton实例设置为未定义后的Angular 变量引用持久性行为

如何检测当前是否没有按下键盘上的键?

如果未定义,如何添加全局变量

CSS网格使页面自动滚动

使用Firebase实时数据库`update`在同一 node 上执行多个更新

Iterator.Next不是进行socket.end()调用后的函数

如何调用多个$HTTP.POST请求?

如何在Angular中分离桌面和移动页面并延迟加载每个页面?

从对象数组上载图像(多个)

如何用JAVASCRIPT更新背景位置值来实现CSS视差滚动?

promise 封装未知数量的异步工作(即其他promise )