【发布时间】:2021-12-05 14:48:54
【问题描述】:
我正在构建一个自定义下拉组件,并且我正在使用 redux 工具包来管理状态。它工作得很好
但是当我在另一个地方重用下拉组件时,在同一页面中,“状态冲突”,所以当我打开一个下拉菜单时,另一个打开。 (这是我的下拉减速器)
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
interface Dropdown {
isOpen: boolean;
selectedValue: string;
}
export const toggleOpen = createAction("dropdown/toggleOpen");
export const changeSelectedValue = createAction<string>(
"dropdown/changeSelectedValue"
);
const initialState = {
isOpen: false,
selectedValue: "-- Selecione --",
} as Dropdown;
const dropdownReducer = createReducer(initialState, (builder) => {
builder
.addCase(toggleOpen, (state) => {
state.isOpen = !state.isOpen;
})
.addCase(changeSelectedValue, (state, action) => {
state.selectedValue = action.payload;
});
});
const dropdownStore = configureStore({
reducer: dropdownReducer,
});
type RootState = ReturnType<typeof dropdownStore.getState>;
type AppDispatch = typeof dropdownStore.dispatch;
export const useDropdownDispatch = () => useDispatch<AppDispatch>();
export const useDropdownSelector: TypedUseSelectorHook<RootState> = useSelector;
export default dropdownStore;
有什么方法可以为同一家商店创建不同的“实例”,所以每个下拉菜单都有自己的? PS:我是在Dropdown组件中填充Provider,所以每个下拉菜单都有一个provider,如下:
import React from "react";
import { Provider } from "react-redux";
import ArrowDown from "../assets/icons/arrow-down";
import ArrowUp from "../assets/icons/arrow-up";
import store, {
useDropdownSelector,
useDropdownDispatch,
toggleOpen,
changeSelectedValue,
} from "../store/reducers/dropdown";
import styles from "./SingleDropdown.module.scss";
interface ItemProps {
value: string;
onClick?: (value: string) => void;
}
const ArrowIcon = () => {
const isOpen = useDropdownSelector((state) => state.isOpen);
return isOpen ? <ArrowUp /> : <ArrowDown />;
};
export const SelectItem: React.FC<ItemProps> = ({
children,
value,
onClick,
}) => {
const dispatch = useDropdownDispatch();
const changeSelectedValueClickHandler = () => {
dispatch(changeSelectedValue(value));
if (onClick) onClick(value);
};
return (
<div
className={styles.dropdown__menu__items}
onClick={changeSelectedValueClickHandler}
id={value}
>
{children}
</div>
);
};
const SelectMenu: React.FC = ({ children }) => {
const isOpen = useDropdownSelector((state) => state.isOpen);
return isOpen ? (
<div className={styles.dropdown__menu}>{children}</div>
) : null;
};
const InitialSelectItem = () => {
const selectedValue = useDropdownSelector((state) => state.selectedValue);
const dispatch = useDropdownDispatch();
return (
<div
onClick={() => dispatch(toggleOpen())}
className={styles.dropdown__field}
>
{selectedValue}
<ArrowIcon />
</div>
);
};
export const SingleSelect: React.FC = ({ children }) => {
return (
<Provider store={store}>
<div className={styles.dropdown}>
<InitialSelectItem />
<SelectMenu>{children}</SelectMenu>
</div>
</Provider>
);
};
【问题讨论】:
-
您应该在另一个唯一属性下维护每个输入状态。可能它应该是输入字段的名称。您可以通过使用页面/表单名称嵌套来避免跨页面的相同问题。
标签: reactjs redux react-redux redux-toolkit state-management