我在我的项目中使用redux与typescript。我的redux初始状态是:
const initailState={
lots:[],
isLoading:false,
error:""
}
我想做的就是查看'state '。当我在布局组件中使用console.log时,我看到这个错误:
对象类型为"未知"。
这是我的商店:
import { shoppingReducers } from "./shopping/shoppingReducer.tsx";
export let store=createStore(shoppingReducers)
export type RootState = ReturnType<typeof store.getState>
下面是layout组件:
const Layout = ({children}:{
children:React.ReactNode
}) => {
const state=useSelector((state) => state.lots)
return (<>
{
console.log(state)
}
</>
当然,我没有忘记提供store in app组件:
import {store} from '../redux/store'
import { Provider } from 'react-redux';
return(<>
<Layout>
<Component {...pageProps} />
</Layout>
</>)
我尝试使用另一个解决方案:在hooks.ts:
中添加自定义选择器钩子import { TypedUseSelectorHook, useSelector } from 'react-redux'
import type { RootState} from './redux/store'
然后我将这个钩子添加到布局组件中使用:
import { useAppSelector } from '../hooks';
const state=useAppSelector((state) => state.lots)
但是我收到了同样的错误!
我现在该怎么办?
更新:这里是减速器:
interface LotsState {
lots: string[];
isLoading: boolean;
error: string;
}
export const initailState:LotsState={
lots:[],
isLoading:false,
error:""
}
export const shoppingReducers=(action:any,state:LotsState=initailState)=>{
switch (action) {
// cases to fetch lots from api :
case GetLotsRequest:
return{...initailState,isLoading:true}
break;
case GetLotsSuccess:
return{...initailState,lots:action.payload.lots,isLoading:false}
break;
case GetLotsFail:
return{...initailState,error:action.payload.error,isLoading:false}
break;
default:
return state
break;
}
}
actions文件:
export const GetLotsRequest=()=>{
return {
type:GET_LOTS_REQUEST
}
}
export const GetLotsSuccess=(lots:Array<any>)=>{
return {
type:GET_LOTS_SUCCESS,
payload:{lots:lots},
}
}
export const GetLotsFail=(error:string)=>{
return {
type:GET_LOTS_FAIL,
payload:{error:error}
}
}
您需要为Reducer提供一个类型。因为您没有在示例中提供reducer代码,所以很难说这是否是原因,但是如果没有键入reducer,则会抛出此类错误。
。state
参数需要有一个像LotsState
这样的类型,您可以这样使用它(接口属性类型只是为了这个例子而创建的):
interface LotsState {
lots: string[];
isLoading: boolean;
error: string;
}
const initailState: LotsState = {
lots: [],
isLoading: false,
error: "",
}
// Important for the state parameter to use the LotsState type
// The action parameter would also benefit from having a type, but its usability was not provided in your example, so I just have a mock type called LotsAction
export const LotsReducer = (state: LotsState = initailState, action: LotsAction = initialAction): LotsState => {
// reducer code here
这太愚蠢了。但在我的情况下,问题是。tsx后缀导入:
import { shoppingReducers } from "./shopping/shoppingReducer.tsx";
我把它改成:
import { shoppingReducers } from "./shopping/shoppingReducer
成功了!当然shoppingReducer文件仍然有。tsx后缀,但我不应该在导入时写这个!