首页 > 解决方案 > 使用带有复杂对象的钩子设置提供者值时无法更新上下文状态

问题描述

当我调用toggleFilterSidebar它时,它应该将 filterSidebarIsOpen 的状态从 false 切换为 true,反之亦然,但 onClick 什么也没有发生,但是当我将 Provider 值直接作为对象传递时,它可以工作。

为什么这行得通?

1)。

return <FilterSidebarContext.Provider value={{
    toggleFilterSidebar,
    filterSidebarIsOpen,
    filters,
  }}>{children}</FilterSidebarContext.Provider>;

而这并没有

2)。

  const [value] = useState({
    toggleFilterSidebar,
    filterSidebarIsOpen,
    filters,
  });

  return <FilterSidebarContext.Provider value={value}>{children}</FilterSidebarContext.Provider>;

我的代码

FilterSidebar.context.js

import React, { useState } from 'react';

export const FilterSidebarContext = React.createContext({});

export const FilterSidebarProvider = ({ children }) => {
  const [filterSidebarIsOpen, setFilterSidebarIsOpen] = useState(true);
  const toggleFilterSidebar = () => setFilterSidebarIsOpen(!filterSidebarIsOpen);
  const [filters] = useState({ regions: [] });

  const [value] = useState({
    toggleFilterSidebar,
    filterSidebarIsOpen,
    filters,
  });

  return <FilterSidebarContext.Provider value={value}>{children}</FilterSidebarContext.Provider>;
};

export const FilterSidebarConsumer = FilterSidebarContext.Consumer;
export default FilterSidebarContext;

过滤按钮.js

const FilterButton = ({ className, getTotalActiveFilters }) => {
  const { toggleFilterSidebar, filterSidebarIsOpen } = useContext(FilterSidebarContext);

  return <Button className={cx({ [active]: filterSidebarIsOpen })} onClick={toggleFilterSidebar} />;
};

标签: javascriptreactjsreact-hooks

解决方案


使用此代码:

  const [value] = useState({
    toggleFilterSidebar,
    filterSidebarIsOpen,
    filters,
  });

您提供useState了一个初始值,该初始值仅在首次安装组件时使用。由于您甚至没有为 setter 创建变量(例如) ,因此永远不可能value更改。const [value, setValue] = useState(...)

我假设您在useState这里使用是为了避免每次渲染都创建一个新对象,从而强制重新渲染依赖于上下文的所有内容,即使它没有改变。用于此目的的适当钩子是useMemo

  const value = useMemo(()=>({
    toggleFilterSidebar,
    filterSidebarIsOpen,
    filters
  })[filterSidebarIsOpen]);

我只放入filterSidebarIsOpen了依赖项数组,因为对于您当前的代码,它是三个可以更改的唯一一个(toggleFilterSidebar是一个不会改变的状态设置器,filters目前没有设置器,所以它不能改变)。


推荐阅读