当前位置: 首页 > 知识库问答 >
问题:

前端 - 请问React(或者zustand)中是否可以对已经存在的状态做监听生成一个新的状态?

慕容兴贤
2025-01-20

使用的是zustand的三方状态库,
有一个场景:store中有一个数组 bearList,我想要在bearList的元素数量为1的时候,触发事件。
是否可以用一个新的状态名来进行代替bearList的数量是否为1呢?比如:bearCountOne: boolean。

在vue中好像有watch的组件属性可以实现这样的功能,但是在react中是否有类似的方式呢?

共有2个答案

鲁丰
2025-01-20

推荐1和3,简单的store里直接派生就可以,复杂一些的再用selector更好
store里直接派生:

import create from 'zustand'

const useStore = create((set, get) => ({
  bearList: [],
  bearCountOne: false,
  
  addBear: (bear) => {
    set((state) => ({
      bearList: [...state.bearList, bear],
      bearCountOne: [...state.bearList, bear].length === 1
    }))
  },
  
  removeBear: (id) => {
    set((state) => ({
      bearList: state.bearList.filter(b => b.id !== id),
      bearCountOne: state.bearList.filter(b => b.id !== id).length === 1
    }))
  }
}))

用useEffect:

function BearComponent() {
  const bearList = useStore((state) => state.bearList)
  const setBearCountOne = useStore((state) => state.setBearCountOne)
  
  useEffect(() => {
    setBearCountOne(bearList.length === 1)
  }, [bearList, setBearCountOne])
  
  return (...)
}

用zustand的selector:

import create from 'zustand'

const useStore = create((set, get) => ({
  bearList: [],
  
  getBearCountOne: () => get().bearList.length === 1,
  
  addBear: (bear) => set((state) => ({ 
    bearList: [...state.bearList, bear] 
  })),
  
  removeBear: (id) => set((state) => ({ 
    bearList: state.bearList.filter(b => b.id !== id) 
  }))
}))

// 在组件里用
function Component() {
  const bearCountOne = useStore((state) => state.getBearCountOne())
  // ...
}

用zustand的subscribe方法:

import create from 'zustand'

const useStore = create((set, get) => ({
  bearList: [],
  bearCountOne: false,
  
  addBear: (bear) => set((state) => ({ 
    bearList: [...state.bearList, bear] 
  })),
  
  removeBear: (id) => set((state) => ({ 
    bearList: state.bearList.filter(b => b.id !== id) 
  }))
}))

// 订阅状态变化
useStore.subscribe(
  (state) => state.bearList,
  (bearList) => {
    useStore.setState({ bearCountOne: bearList.length === 1 })
  }
)
濮阳宏硕
2025-01-20

使用 useStore 来管理 bearList 和bearCountOne 的状态,并在 addBear 和 removeBear 方法中更新 bearCountOne 的值。然后在 ExampleComponent 中使用 React.useEffect 来监听bearCountOne 的变化,并在其值为 true 时触发事件。

import create from 'zustand';

const useStore = create((set) => ({
  bearList: [],
  bearCountOne: false,
  error: null,
  addBear: (bear) => set((state) => {
    try {
      const newBearList = [...state.bearList, bear];
      return {
        bearList: newBearList,
        bearCountOne: newBearList.length === 1,
        error: null,
      };
    } catch (error) {
      return { error: 'Failed to add bear' };
    }
  }),
  removeBear: (bear) => set((state) => {
    try {
      const newBearList = state.bearList.filter((b) => b !== bear);
      return {
        bearList: newBearList,
        bearCountOne: newBearList.length === 1,
        error: null,
      };
    } catch (error) {
      return { error: 'Failed to remove bear' };
    }
  }),
}));

// 使用示例
const ExampleComponent = () => {
  const { bearList, bearCountOne, addBear, removeBear, error } = useStore();

  React.useEffect(() => {
    if (bearCountOne) {
      // 触发事件
      console.log('Bear count is one!');
    }
  }, [bearCountOne]);

  return (
    <div>
      <button onClick={() => addBear('Bear')}>Add Bear</button>
      <button onClick={() => removeBear('Bear')}>Remove Bear</button>
      <div>Bear List: {bearList.join(', ')}</div>
      <div>Bear Count One: {bearCountOne.toString()}</div>
      {error && <div style={{ color: 'red' }}>{error}</div>}
    </div>
  );
};
 类似资料:
  • 请问react的状态管理, zustand和jotai 一般需要结合使用吗? 还是说实际项目中只使用其中一种就足够了?

  • 问题内容: 我的组件内部有这个: 问题在于监听器内部不是最新的,因为它不在渲染器内部。它已经连接了。有什么想法我该如何解决? 谢谢! 问题答案: 问题是由于运行效果时形成的闭合。由于您将设置为仅在初始安装时运行,因此它从声明时形成的闭包中获取值,因此即使更新,内部也将引用最初存在的相同值。 由于您不想访问其中的值,而只是根据先前的值更新状态,因此您可以简单地使用setter的回调模式

  • 问题 你想实现一个状态机或者是在不同状态下执行操作的对象,但是又不想在代码中出现太多的条件判断语句。 解决方案 在很多程序中,有些对象会根据状态的不同来执行不同的操作。比如考虑如下的一个连接对象: class Connection: """普通方案,好多个判断语句,效率低下~~""" def __init__(self): self.state = 'CLOSED

  • 问题内容: 我知道React可以异步并批量执行状态更新以优化性能。因此,在调用之后,您将永远无法相信要更新的状态。但是你可以信任的反应 更新相同的顺序状态被称为对 相同的组件? 不同的组件? 考虑在以下示例中单击按钮: 1. 在以下情况下,是否有可能 a为假而b为真 : 2. 在以下情况下,是否有可能 a为假而b为真 : 请记住,这些是我用例的极端简化。我意识到我可以以不同的方式进行操作,例如,在

  • 我知道React可能会异步和批量地执行状态更新,以进行性能优化。因此,在调用之后,您永远不能相信会更新状态。但是,您是否信任React按照调用时的顺序更新状态 相同的组件? 不同的组件? 任何有文档支持的答案都是非常感谢的。

  • 请问在对React项目做状态管理,您们都是使用什么方案呢? React有若干种状态管理的方案,官方使用的Redux/ Redux-Toolkit 是官方推荐的, 请问您们的解决方案是怎么使用的呢? 是否还有比较方便容易使用的方案?

  • 我们正在热烈讨论如何在React中更新嵌套状态。国家是否应该是不可改变的?优雅地更新状态的最佳实践是什么? 假设你有这样的状态结构: 然后我们要更新乔·多伊的电话号码。我们有几种方法可以做到这一点: 将状态强制更新更改为重新加载 带变异状态的变异状态集合状态 Object.assign,这仍然会改变状态,因为new学生只是对this.state指向的同一对象的新引用 更新不变性助手(https:/

  • 请教下 useState 更新的问题,有一个页面,当数据库中没有数据的时候,显示 No user,当数据库中有数据的时候,显示出真实的数据,代码如下 现在我遇到的问题是 每次访问这个页面 /users,都会显示 No user,然后过一会数据完全载入了才会显示正确的数据。查看了下,这里会渲染两次,第一次渲染 activedUsers.length 是 0,第二次渲染才会正确的载入数据。 点击任意一