【发布时间】:2020-02-28 14:04:34
【问题描述】:
我有一个正在工作的 React 上下文,但我想将项目批量加载到状态中。
上下文有一个reducer,用于将单个对象添加到上下文存储的对象数组中。在代码(附加)中,问题区域位于提供程序初始化的底部。在 useEffect 中,这会执行 api fetch 调用。数据返回并且当前使用 reducer 一次加载一个元素。这是低效的,因为它会导致对侦听上下文的组件进行多次渲染调用。
我对 React 和 Typescript 比较陌生,并且难以获得正确的编码和语法来阻止 Typescript 抱怨。
我想更改减速器以接受“加载”操作,其中包含替换状态数组中所有当前元素的项目数组的有效负载。我有一个特殊的加载操作,并且一直在尝试将该操作的有效负载作为一个数组,而不更改接受单个项目的其他操作。或者提供一个新函数,将一组对象加载到状态中。
我尝试将 IAction 中的有效负载定义为有效负载:NewsItemType|Array, item NewsItemType }
无论我尝试什么,我都会在 reducer 中遇到语法错误:React.Reducer - 主要是关于返回类型。
任何人都可以提供有关最佳方法的建议吗?
import * as React from "react";
/** Custom types */
import { ActionType } from "../custom-types";
import { NewsItemType } from "../custom-types";
import { apiRequest } from "../utils/Helpers";
const MAX_ITEMS = 30;
interface IState {
newsList: Array<NewsItemType>;
}
interface IAction {
type: ActionType;
payload: NewsItemType;
}
interface InewsContextInterface {
state: {
newsList: Array<NewsItemType>;
};
updateNewsList: React.Dispatch<IAction>;
}
const initialState: IState = { newsList: [] };
const reducer: React.Reducer<IState, IAction> = (state, action) => {
switch (action.type) {
case ActionType.add:
return {
newsList: [
action.payload,
...state.newsList.filter(
newsitem => newsitem._id !== action.payload._id
)
]
};
case ActionType.load:
return {
newsList: [...state.newsList, action.payload]
};
case ActionType.update:
return {
newsList: state.newsList.map(item => {
return item._id === action.payload._id ? action.payload : item;
})
};
case ActionType.delete:
return {
newsList: state.newsList.filter(
newsitem => newsitem._id !== action.payload._id
)
};
default:
throw new Error();
}
};
export const newsContext = React.createContext<InewsContextInterface>({
state: {
newsList: []
},
updateNewsList: () => { }
});
const { Provider } = newsContext;
const NewsProvider: React.FC<{ children: React.ReactNode }> = ({
children
}) => {
const [newsList, updateNewsList] = React.useReducer(reducer, initialState);
React.useEffect(() => {
apiRequest("http://localhost:5000/news/?limit=" + MAX_ITEMS, "get", true)
.then(news => {
if (news) {
Array.from(news).forEach((article: any) =>
updateNewsList({ type: ActionType.load, payload: article })
);
}
})
.catch(alert => {
console.error(alert);
});
}, []);
return (
<Provider value={{ state: newsList, updateNewsList }}>{children}</Provider>
);
};
export default NewsProvider;
【问题讨论】:
-
你能发布你看到的错误吗?
-
将payload更改为:interface IAction { type: ActionType;有效载荷:NewsItemType |数组
;我在减速器声明中收到打字稿错误,其开头为: Type '(state: IState, action: IAction) => { newsList: (NewsItemType | NewsItemType[])[]; }' 不可分配给类型 'Reducer '。调用签名返回类型 '{ newsList: (NewsItemType | NewsItemType[])[]; }' 和 'IState' 不兼容。
标签: reactjs typescript