javascript - 输入'{状态:任何;调度:React.Dispatch<{ 类型:字符串;值:任何;}>; }' 不可分配给类型
问题描述
我正在构建一个 UI,左侧有一些复选框,右侧有一个数据表,还有放置区框,我希望每次放置一个新文件时都能够维护表数据,并根据复选框选择过滤表中的数据,无论如何,我构建了大部分内容,并且能够将选择控件传递给主要组件以过滤/排序数据,后来我尝试添加redux
维护应用程序的状态,但它不能顺利使用钩子,并且它一直抱怨从函数组件体外部调用钩子,尽管它们不是。我得出的结论是,它们不能很好地协同工作,并切换了使用context
和redux
一起维护状态并构建这个组件,但是我遇到了编译问题,自从我使用 react/hooks/redux 已经 2 年了,我觉得过去 2 年事情发生了变化。
**) 我关于 redux 和 hooks 冲突的结论对吗?如果没有,你能不能给它一些亮点?
下面是代码和错误,有问题的行是
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 };
输入'{状态:任何;调度:React.Dispatch<{ 类型:字符串;值:任何;}>; }' 不可分配给类型 '{ state: { searchFilter: string[]; 数据行:数据行[];}; }'。对象字面量只能指定已知属性,而 'dispatch' 不存在于类型 '{ state: { searchFilter: string[]; 数据行:数据行[];}; }'.ts(2322) index.d.ts(339, 9): 预期的类型来自属性'value',它在类型'IntrinsicAttributes & ProviderProps<{ state: { searchFilter: string[]; 数据行:数据行[];}; }>'
解决方案
由于我们有useReducer
钩子,大多数时候我们不需要使用 redux 或任何其他类似 redux 的库。
要解决类型问题,您需要定义一个ContextType
.
interface ContextType {
state: {
searchFilter: string[];
dataRows: DataRow[];
};
dispatch: React.Dispatch<{ type: string; value: unknown }>;
}
要创建您的商店上下文,您可以使用以下内容。(我们允许它为空,因此我们在创建上下文时不必处理初始值。消费者需要确保已定义上下文 - 请参见下面的几行)
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
推荐阅读
- html - 在 Github 中,如何让 index.html 在我的托管网站中自动打开
- python - Tkinter:不断更新变量
- git - GitHub:当分支与 master 没有更多共同历史记录时如何重新打开拉取请求
- video-streaming - WebRTC 如何根据自适应比特率确定何时调整视频大小?
- c++ - 使用辅助临时对象方便的“回写”
- vim - 打开 url 时在命令中转义 `#`
- javascript - 使用 `status == true` 时,布尔条件始终为假
- python - 从 SQLite 检索数据时出现语法错误
- perl - IO::Socket::INET 发送中的宽字符
- javascript - forEach 不等到承诺解决