javascript - 使用带有复杂对象的钩子设置提供者值时无法更新上下文状态
问题描述
当我调用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} />;
};
解决方案
使用此代码:
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
目前没有设置器,所以它不能改变)。
推荐阅读
- sql - 如何根据某些参数对月份日期进行四舍五入
- mysql - 无法创建存储过程,但其中的所有内容都运行得很好
- python - 如何在同时启动另一个窗口的类时使窗口不仅显示一次?
- oracle - 程序没有结束
- c# - System.Threading.ThreadStateException(可能是引发条件)
- android - tif 和 tiff 图像未显示带有 React Native 的 Image 组件的 android
- excel - Excel 宏到 Google 表格
- c++ - C++17 依赖名称不是类型,适用于 C++14
- python - 一定距离内的位置数
- sql - 将数据保存在变量中的查询