类型 '{ state: any; dispatch: React.Dispatch<{ type: string; value: any; }>; }' 不可分配给类型



我正在构建一个 UI,左侧有一些复选框,右侧有一些数据表,还有拖放区框,我希望每次我放一个新文件时都能维护表数据,并根据复选框选择过滤表中的数据, 我构建了大部分,并且能够将选择控件传递给主组件以过滤/排序数据,后来我尝试添加redux来维护应用程序的状态,但它不能顺利地与钩子一起使用,并且它一直抱怨从函数组件主体外部调用钩子, 虽然他们不是。我得出的结论是它们不能很好地协同工作,并切换齿轮以一起使用contextredux来维护状态并构建此组件,但我遇到了编译问题,自从我使用 react/hooks/redux 以来已经有 2 年了,我觉得过去 2 年情况发生了变化。

**(我关于 redux 和钩子之间冲突的结论是正确的吗?如果没有,你能不能给它一些启示?

下面是代码和错误,有问题的行是return <Provider value={{ state, dispatch }}>{children}</Provider>;

store.tsx

// store.js
import React, {createContext, useReducer} from 'react';
import { useDispatch } from 'react-redux'
import DataRow from '../types/datarow';
//define empty filters array
const initFilter : string[] = [];
const initDataRows : DataRow[] = [];
const initialState = {
searchFilter: initFilter,
dataRows: initDataRows
};
// const dispatch: React.Dispatch<{
//     type: string;
//     value: any;
// }>= {};
//const dispatch = useDispatch();
const context = {
state: initialState,
//dispatch: dispatch({type:"dataIssueChecked", value: "Missing"})
};
type stateType = {
searchFilter: [],
dataRows: DataRow[]
};
const store = createContext(context);
const { Provider } = store;
const StateProvider = ( { children} : any ) => {
const [state, dispatch] = useReducer((state : any, action:{type:string, value:any}) => {
switch(action.type) {
case "dateChecked": 
console.log("dateChecked: ", action.value);
if(state.searchFilter.includes(action.value)){
const searchFilter = state.searchFilter.filter((v: string) => v !== action.value);
const newState = { ...state, searchFilter };
//state.searchFilter = newSearchFilter;
return newState;
}else{
state.searchFilter.push(action.value);
}  
break;
case "dataIssueChecked":
if(state.searchFilter.includes(action.value)){
let searchFilter = state.searchFilter.filter((v: string) => v !== action.value);
const newState = { ...state, searchFilter };
return newState;
}else{
state.searchFilter.push(action.value);
}
break;
case "UPDATE_TABLE":
state.dataRows =  action.value;
break;
default:
throw new Error();
};
}, initialState);
return <Provider value={{ state, dispatch }}>{children}</Provider>;
};
export { store, StateProvider };

键入 '{ state: any; dispatch: React.Dispatch<{ type: string; value: any; }>;}' 不能分配给类型 '{ state: { searchFilter: string[]; dataRows: DataRow[]; }; }'。 对象文字可能只指定已知属性,并且类型"{ state: { searchFilter: string[]; dataRows: DataRow[]; }; }' 中不存在 'dispatch'。TS(2322( index.d.ts(339, 9(:预期的类型来自属性"value",该属性在类型"IntrinsicAttributes & ProviderProps<{ state: { searchFilter: string[]; dataRows: DataRow[]; }; }>'

由于我们有useReducer钩子,大多数时候我们不需要使用 redux 或任何其他类似 redux 的库。

要解决类型问题,您需要定义一个ContextType

interface ContextType {
state: {
searchFilter: string[];
dataRows: DataRow[];
};
dispatch: React.Dispatch<{ type: string; value: unknown }>;
}

要创建商店上下文,您可以使用以下内容。(我们允许它为 null,因此在创建上下文时我们不必处理初始值。使用者需要确保上下文已定义 - 请参阅下面的几行(

const store = createContext<ContextType | null>(null);

然后,您可以创建useStore挂钩以访问存储中的数据。

function useStore() {
const value = React.useContext(store);
if (!value) throw new Error("useStore needs to be within StateProvider");
return value;
}

您可以在此处查看一个实时示例 https://codesandbox.io/s/winter-architecture-s2i5q

相关内容

最新更新