【问题标题】:React hook state - does not update component反应钩子状态 - 不更新组件
【发布时间】:2021-05-19 05:50:27
【问题描述】:

所以我正在运行具有以下设置的应用程序:

  • Hook - 提供 statesetter 来更新状态
  • 组件 A - 仅使用挂钩中的 状态 并显示其中的数据
  • 组件 B - 仅使用 setter 并更新 hooks 状态

但是,在我当前的设置中,当钩子状态确实在数组中获得新项目时,组件 A 不会重新呈现,任何想法为什么会发生这种情况?我提供了一些代码进行澄清:

挂钩

const initialValue = [];

function getLocalStorageItem() {
  const item = window.localStorage.getItem("queries");
  return item ? JSON.parse(item) : initialValue;
}

function useLocalStorageQueryHistory() {
  const { dispatch } = useAlertContext();

  const [recentQueries, setRecentQueries] = useState(() => {
    try {
      return getLocalStorageItem();
    } catch (error) {
      dispatch(receiveMessageInterceptor(error));
      return initialValue;
    }
  });

  const setValue = (value) => {
    try {
      const recentQueries = getLocalStorageItem();
      if (recentQueries.length >= 6) {
        recentQueries.shift();
      }

      if (!recentQueries.some((query) => query.params === value.params)) {
        window.localStorage.setItem(
          "queries",
          JSON.stringify([...recentQueries, value])
        );
        setRecentQueries([...recentQueries, value]);
      }
    } catch (error) {
      dispatch(receiveMessageInterceptor(error));
    }
  };

  return { recentQueries, setValue };
}

组件 A

function RecentQueriesContainer() {
  const { recentQueries } = useLocalStorageQueryHistory();

  return (
    <Container disableGutters>
        {recentQueries.length ? (
          recentQueries.map((item) => (
            <Card key={`${item.params}`}>
              <CardHeader
                title={item.description}
              />
                  <Typography variant={"body2"}>
                    Mode: {item.params.split("&visualization=")[1]}
                  </Typography>
                  <Typography variant={"body2"}>Unit: {item.unit}</Typography>
            </Card>
          ))
        ) : (
          <Typography
            variant={"subtitle2"}
            color={"secondary"}
            align={"center"}
            mt={2}
          >
            No recent queries available
          </Typography>
        )}
    </Container>
  );
}

组件 B

只在useEffect中使用setter

useEffect(() => {
    const {
      features,
      description,
      unit,
      amountOfCountries,
    } = geoJsonFromSelectedStatistic;
    if (features) {
      setValue({
        description,
        unit,
        amountOfCountries,
        params: window.location.search,
      });
    }
  }, [geoJsonFromSelectedStatistic]);

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    我相信这是因为您没有创建上下文。 Hooks 默认不共享状态,它们只共享状态逻辑

    所以组件 A 和 B 使用的是同一个钩子,但是它们之间的状态不同。

    尝试创建一个上下文,然后使用它来共享状态。它应该可以正常工作:)

    const AuthContext = createContext({});
    
    export const AuthProvider = ({ children }) => {
      const [isAuthenticated, setIsAuthenticated] = useState();
    
      return (
        <AuthContext.Provider value={{ isAuthenticated, setIsAuthenticated }}>
          {children}
        </AuthContext.Provider>
      );
    };
    
    export function useAuth(){
      const context = useContext(AuthContext);
    
      if (!context) {
        throw new Error('useAuth must be used within an AuthProvider');
      }
      return context;
    }
    

    类似这样的东西,其中 AuthProvider 就像您的自定义挂钩,其值是您的挂钩导出的值。这些将可用于上下文与 useAuth 一起使用的任何组件

    不要忘记使用 &lt;AuthProvider /&gt; 包装您的应用

    【讨论】:

      【解决方案2】:

      我遵循@thales-kenne 的方法并使用我已经设置了 UI 上下文的反应上下文并将其扩展如下:

      UI-context.js

      const initialState = {
        sidebarOpen: false,
        ...
        recentQueries: getLocalStorageItem(),
      };
      
      function uiReducer(state = initialState, action) {
        switch (action.type) {
          case SIDEBAR: {
            return {
              ...state,
              sidebarOpen: action.sidebarOpen,
            };
          }
          ...
          case RECENT_QUERIES: {
            return {
              ...state,
              recentQueries: action.recentQueries,
            };
          }
          default:
            return state;
        }
      }
      

      UI-actions.js

      export function getLocalStorageItem() {
        const initialValue = [];
        try {
          const item = window.localStorage.getItem("queries");
          return item ? JSON.parse(item) : initialValue;
        } catch (error) {
          console.error(error);
          return initialValue;
        }
      }
      
      export const setRecentQueries = (value) => {
        try {
          const recentQueries = getLocalStorageItem();
          if (recentQueries.length >= 5) {
            recentQueries.shift();
          }
      
          if (!recentQueries.some((query) => query.uri === value.uri)) {
            window.localStorage.setItem(
              "queries",
              JSON.stringify([...recentQueries, value])
            );
            return {
              type: RECENT_QUERIES,
              recentQueries: [...recentQueries, value],
            };
          }
        } catch (error) {
          console.error(error);
        }
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-19
        • 1970-01-01
        • 1970-01-01
        • 2021-11-12
        • 2019-09-17
        • 2021-10-23
        • 2017-09-10
        • 2020-02-12
        相关资源
        最近更新 更多