我已经在Typescript中设置了我的redux存储,如下所示。然而,当我试图在主组件IDE中使用useSelector获取火箭时,出现错误
const rockets = useSelector((state: RootState) => state.rocketList.rockets);
错误消息-类型"never"上不存在属性"rockets">
配置Store.tsx
import { combineReducers, createStore } from "redux";
import rocketsReducer from "./ducks/rockets";
export const rootReducer = combineReducers({
rocketList: rocketsReducer,
});
const store = createStore(rootReducer);
export default store;
rockets.tsx(这遵循1个文件中的动作、减速器和类型的鸭子模式(
import { IAction, IRocket } from "../../Interfaces";
const STOREROCKETS = "storeRockets";
export const storeRockets = (rockets: IAction) => ({
type: STOREROCKETS,
payload: rockets,
});
type RocketState = {
rockets: IRocket[]
}
const initialState: RocketState = {
rockets: [],
};
export default (state:RocketState = initialState, action: IAction) => {
switch (action.type) {
case STOREROCKETS:
return { ...state, rockets: action.payload };
default:
return state;
}
};
接口.ts
import { rootReducer } from "./redux/configureStore";
export type RootState = ReturnType<typeof rootReducer>
export interface IRockets {
rockets: IRocket[]
}
export interface IAction {
type: string
payload: { type: string, payload: object[] }
}
export interface IRocket {
id: string
name: string
description: string
success_rate_pct: number
active: boolean
first_flight: string
wikipedia: string
cost_per_launch: number
flickr_images: string[]
}
主页.tsx
import { RootState } from "../Interfaces";
const Home: FC = () => {
const [isLoading, setIsLoading] = useState<Boolean>(false);
const dispatch = useDispatch();
const [showError, setShowError] = useState<Boolean>(false);
const [errorText, setErrorText] = useState<String>("");
const rockets = useSelector((state: RootState) => state.rocketList.rockets);
在动作类型的定义中有过多的对象嵌套:
export interface IAction {
type: string
payload: { type: string, payload: object[] }
}
和行动创造者:
export const storeRockets = (rockets: IAction) => ({
type: STOREROCKETS,
payload: rockets,
});
假设我有一系列火箭:
const rockets: IRocket[] = [];
我希望称动作创作者为:
storeRockets(rockets);
得到这样的结果:
{
type: "storeRockets",
payload: [],
}
但相反,你的类型决定了你必须这样称呼它:
storeRockets({
type: "sometype",
payload: {
type: "otherType",
payload: rockets
}
})
然后动作创建者添加另一个级别的type
!所以你的实际行动是:
{
type: "storeRockets",
payload: {
type: "sometype",
payload: {
type: "otherType",
payload: [],
}
}
}
这是代码中的主要问题。
您应该将您的操作类型更改为此。它修复了嵌套问题,还使用了特定的对象类型IRocket
而不是object
。
export interface IAction {
type: string;
payload: IRocket[]
}
您的动作创建者应该只执行payload
,而不是整个动作。它返回一个IAction
。
export const storeRockets = (rockets: IRocket[]): IAction => ({
type: STOREROCKETS,
payload: rockets
});
我建议您在reducer上设置一个显式返回类型,这样,如果您没有像以前那样返回预期的类型,就会出现错误。
export default (state: RocketState = initialState, action: IAction): RocketState => {
我还建议您创建一个已经知道RootState
类型的useSelector
钩子,这样您就不必每次都声明它。
import { createSelectorHook } from "react-redux";
export const useSelector = createSelectorHook<RootState>();