尝试将状态从一个组件共享到另一个组件:可以从主组件访问状态,但从新组件访问时状态未定义 这是我的减速器:
export const tableReducer=(state = [], action)=> {
switch (action.type) {
case 'SELECTED_LIST':
state = JSON.parse(JSON.stringify(action.payload));
return state;
default:
return state
}
}
Run Code Online (Sandbox Code Playgroud)
从不同的文件访问它:
const [userList, usersDispatch] = useReducer(tableReducer, []);
useEffect(() => {
const list = Object.keys(selectedRowIds).length > 0 ? selectedFlatRows.map(
d => d.original.email
)
: '';
usersDispatch({ type: 'SELECTED_LIST', payload: list, });
}, [selectedRowIds, selectedFlatRows]);
Run Code Online (Sandbox Code Playgroud)
并在一个新组件中:
const [userList] = useReducer(tableReducer);
const deleteUsers = () => {
console.log(userList)
}
Run Code Online (Sandbox Code Playgroud)
但这里的console.log(userList)结果是undefined
您无法useReducer像您尝试的那样与 hook 共享状态。每次调用都会useReducer返回一个新状态,该状态使用传递给useReducerhook 的减速器函数进行管理。
正如每次调用都会useState返回不同的状态一样,每次调用都会useReducer返回不同的状态。两个useReducer调用不能共享相同的状态。
要共享状态,您可以使用以下选项之一:
对于组件之间的状态共享,您可以使用带有 useReducer 的 Context API。
Context API 提供了一种简洁的方式来为子组件提供状态,而不会以道具钻取情况结束。它要求 aProvider被设置,它将其值提供给它的任何Consumers. 作为 的子组件的任何组件都Provider可以使用上下文。
首先创建一段上下文。
自定义上下文.js
import React from 'react';
const CustomContext = React.createContext();
export function useCustomContext() {
return React.useContext(CustomContext);
}
export default CustomContext;
Run Code Online (Sandbox Code Playgroud)
我们可以在单独的文件中定义您的减速器。
TableReducer.js
export const tableReducer=(state = [], action)=> {
switch (action.type) {
case 'SELECTED_LIST':
state = JSON.parse(JSON.stringify(action.payload));
return state;
default:
return state
}
}
Run Code Online (Sandbox Code Playgroud)
接下来是实现提供者,并在“父”组件(更高的组件)中给它一个值
import CustomContext from './CustomContext'
import { tableReducer } from './TableReducer'
const ParentComponent = () => {
const [userState, usersDispatch ] = React.useReducer(tableReducer, []);
const providerState = {
userState,
usersDispatch
}
return (
<CustomContext.Provider value={providerState} >
<ChildComponent /> //Any component within here can access value by using useCustomContext();
</CustomContext.Provider>
)
}
Run Code Online (Sandbox Code Playgroud)
现在,任何嵌套在 <CustomContext.Provider></CustomContext.Provider> 中的组件都可以访问传递Provider给上下文状态和调度方法的“value”属性的任何内容。
子组件看起来像这样(我已经省略了你的状态值等等......)
import { useCustomContext }from './CustomContext'
const ChildComponent = (props) => {
//your custom state variables and other methods
const { userState, usersDispatch } = useCustomContext();
useEffect(() => {
const list = Object.keys(selectedRowIds).length > 0 ? selectedFlatRows.map(
d => d.original.email
)
: '';
usersDispatch({ type: 'SELECTED_LIST', payload: list, });
}, [selectedRowIds, selectedFlatRows]);
return(
<div>your components dependent on selectedRowIds, selectedFlatRows<div>
)
}
Run Code Online (Sandbox Code Playgroud)
@Gandzal 是正确的,但我发现它缺少打字稿版本,而且今天 createContext 需要一个默认参数。这是谷歌上最热门的答案之一,所以我想我会分享。
我这样设置我的解决方案:
自定义上下文:
import React, {Dispatch} from 'react';
import {StateType, Action} from './reducer'
interface IContextProps {
state: StateType;
dispatch:Dispatch<Action>
}
const CustomContext = React.createContext({} as IContextProps);
export function useCustomContext() {
return React.useContext(CustomContext);
}
export default CustomContext;
Run Code Online (Sandbox Code Playgroud)
注意 StateType 和 Action:
export type StateType = {
items: Array<DataItems>;
date: Date;
};
export type Action = {
type: ActionKind;
payload: DataItems;
};
Run Code Online (Sandbox Code Playgroud)
减速器:
export const reducer = (state: StateType, action: Action) => {
const { type, payload } = action;
let newArray: Array<DataItems> = [];
switch (type) {
case ActionKind.Checked:
newArray = state.items.map((item) => ({
...item,
checked: item.id === payload.id ? true : item.checked,
}));
return {
...state,
items: newArray,
}
default:
return state;
}
};
Run Code Online (Sandbox Code Playgroud)
应用程序.tsx:
import { reducer, initalState } from 'Shared/Reducer/reducer';
import CustomContext from 'Shared/Reducer/CustomContext';
const App: React.FC = () => {
const [state, dispatch] = React.useReducer(reducer, initalState);
const providerState = {
state,
dispatch,
};
return (
<CustomContext.Provider value={providerState}>
<main role="main">
// your components
</main>
</CustomContext.Provider>
);
};
export default App;
Run Code Online (Sandbox Code Playgroud)
还有你的组件之一:
import { useCustomContext } from 'Shared/Reducer/CustomContext';
export const MyComp: React.FC<MyType> = (props) => {
const { data} = props;
const { state, dispatch } = useCustomContext(); --- Your state and dispatch here
return (
<div>
// your component
</div >
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2154 次 |
| 最近记录: |