首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Zustand正在更新单个属性状态更改上的所有组件。

Zustand正在更新单个属性状态更改上的所有组件。
EN

Stack Overflow用户
提问于 2022-04-24 03:24:56
回答 2查看 2.9K关注 0票数 1

在每次状态更改时,都会呈现两个使用Zustand存储的不同子组件。虽然它们在组件中使用的状态属性没有更新。我不会在组件中使用整个存储,只是尝试利用存储片。这是组件

代码语言:javascript
复制
//Store
    import create from "zustand";
    
    export const useStore = create((set) => ({
      shows: [
        {
          id: Math.floor(Math.random() * 100),
          name: "River Where the Moon Rises",
        },
        {
          id: Math.floor(Math.random() * 100),
          name: "The Crowned Clown",
        },
      ],
      title: 'Default Title',
      addShow: (payload) => set((state) => {state.shows.push({id:Math.floor(Math.random() * 100), name:payload})}),
      updateTitle: (newTitle) => set({title:newTitle}),
    }));

    
//App - component

    function App() {
          return (
            <>
              <ShowManagement />
              <TitleManagement />
            </>
          );
        }
        
        export default App;


//ShowManagement  - component

    import React from 'react'
    import { useStore } from "../hooks/useStore";
    
    const ShowManagement = () => {
        const { shows } = useStore((state) => ({ shows: state.shows }));
        const { addShow } = useStore((state) => ({addShow: state.addShow }));
    
        console.log('ShowManagement - reloaded');
      return (
        <>
          <div>ShowManagement</div>
          <ul>
            {shows?.map((drama) => {
              return (
                <li>
                  {drama.id} - {drama.name}
                </li>
              );
            })}
          </ul>
          <div>
            <input width={200} id="dramaText" />
            <button
              onClick={() => addShow(document.getElementById("dramaText").value)}
            >
              Add Drama
            </button>
          </div>
        </>
      );
    }
    
    export default ShowManagement

//TitleManagement - component

import React from 'react'
import { useStore } from "../hooks/useStore";

const TitleManagement = () => {

    const { title } = useStore((state) => ({title:state.title}));
    const { updateTitle } = useStore((state) => ({updateTitle: state.updateTitle}));
    console.log("TitleManagement - reloaded");


  return (
    <div>
      <p>{title}</p>
      <button
        onClick={() => updateTitle('Title From UI')}
      >
        Update Title
      </button>
    </div>
  );
}

export default TitleManagement

组件不应在其他状态属性更改时呈现。

EN

回答 2

Stack Overflow用户

发布于 2022-05-14 00:05:51

尝尝这个。

不知道为什么要在返回时创建一个“新”对象,因为您只是在破坏这个值。因此,对于所有的状态选择器,不要返回一个新对象--这将“永远”是一个新的引用,因此您将始终得到一个新的重新呈现。

只要得到你所需要的状态,不要对你所返回的东西产生幻想。

代码语言:javascript
复制
const title = useStore((state) => state.title);
const updateTitle = useStore((state) => state.updateTitle);

这似乎很有效:https://codesandbox.io/s/elegant-rain-fy4g4v?file=/src/App.js

请记住,如果您使用react 18,您将看到两个呈现。所以,在密码箱里,我用的是反应17‘ish.以及作站3+

如果您不关心这两种呈现(对于状态更改),那么将它们分别提高到18和4。

您也可以使用“浅”(zustand/浅),这样您的代码如下所示:

代码语言:javascript
复制
  const [ shows, addShow ] = useStore((state) => [state.shows, state.addShow], shallow));
票数 1
EN

Stack Overflow用户

发布于 2022-04-24 22:17:06

所以,我一小时前才开始使用这个库,我觉得它很棒,但仍然停留在同一个问题上。

问题在于比较函数。您可以通过添加自己的比较和一个额外的日志来检查这一点:

代码语言:javascript
复制
const { shows } = useStore((state) => ({ shows: state.shows }), (a, b) => {
    console.log('comparing', a, b)
    return a === b
  })

您将看到两个对象正在进行比较(比较时不会返回true,因此总是更新)。

答案是在自述文件中:

代码语言:javascript
复制
import shallow from 'zustand/shallow'
const { shows } = useStore((state) => ({ shows: state.shows }), shallow)

或者简单地编写自己的比较函数

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71985268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档