【问题标题】:Redux useSelector returns an object with key '0' and value of the state instead of the plain stateRedux useSelector 返回一个带有键 '0' 和状态值的对象,而不是普通状态
【发布时间】:2021-04-01 16:12:46
【问题描述】:

我创建了一个简单的 Redux 应用程序,包含以下部分

import { useDispatch, useSelector } from "react-redux";
import { buyCakes } from "../redux/cake/cake.actions";
import { ICakeState } from "../redux/cake/cake.reducer";
import { changeEventType, formEventType } from "../models/events.model";

const CakeContainer: React.FC = () => {
  const [buyCakeAmount, setBuyCakeAmount] = useState(1);

  const numberOfCakes = useSelector<ICakeState, ICakeState["numberOfCakes"]>(
    (state) => {
      console.log(state);
      return state.numberOfCakes;
    }
  );

  const dispatch = useDispatch();

  const changeHandler = (event: changeEventType) => {
    setBuyCakeAmount(parseInt(event.target.value));
  };

  const submitHandler = (event: formEventType) => {
    event.preventDefault();
    dispatch(buyCakes(buyCakeAmount));
    setBuyCakeAmount(1);
  };

  return (
    <>
      <h2>Number of cakes left in the shop: {numberOfCakes}</h2>
      <form onSubmit={submitHandler}>
        <input type="number" value={buyCakeAmount} onChange={changeHandler} />
        <button type="submit">Buy Cakes</button>
      </form>
    </>
  );
};

export default CakeContainer;

减速器

import { BUY_CAKE, BUY_CAKES } from "./cake.types";
import { CakeActionTypes } from "./cake.types";

export interface ICakeState {
  numberOfCakes: number;
}

const INITIAL_STATE: ICakeState = {
  numberOfCakes: 10,
};

const cakeReducer = (
  state: ICakeState = INITIAL_STATE,
  action: CakeActionTypes
) => {
  switch (action.type) {
    case BUY_CAKE:
      return {
        ...state,
        numberOfCakes: state.numberOfCakes - 1,
      };

    case BUY_CAKES:
      return {
        ...state,
        numberOfCakes: state.numberOfCakes - action.payload,
      };

    default:
      return state;
  }
};

export default cakeReducer;

动作

import { BUY_CAKE, BUY_CAKES } from "./cake.types";
import { CakeActionTypes } from "./cake.types";
import { numberOfCakes } from "../../models/cake.model";

export const buyCake = (): CakeActionTypes => ({
  type: BUY_CAKE,
});

export const buyCakes = (numberOfCakes: numberOfCakes): CakeActionTypes => ({
  type: BUY_CAKES,
  payload: numberOfCakes,
});

类型

import { numberOfCakes } from "../../models/cake.model";

export const BUY_CAKE = "BUY_CAKE";
export const BUY_CAKES = "BUY_CAKES";

interface BuyCakeAction {
  type: typeof BUY_CAKE;
}

interface BuyCakesAction {
  type: typeof BUY_CAKES;
  payload: numberOfCakes;
}

export type CakeActionTypes = BuyCakeAction | BuyCakesAction;

商店

import { combineReducers, createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import cakeReducer from "./cake/cake.reducer";

export default createStore(
  combineReducers([cakeReducer]),
  composeWithDevTools()
);

useSelector 中的日志记录了这个对象

{"0":{"numberOfCakes":10}}

不应该只返回状态而不将其放入键为“0”的对象中吗? 另外,如果我只是返回这样的状态

state['0'].numberOfCakes

我收到打字稿错误 有人可以向我解释为什么会发生这种情况以及如何解决它,谢谢。

【问题讨论】:

    标签: reactjs typescript object redux react-hooks


    【解决方案1】:

    第一个问题:useSelector 将返回您的 root 状态,因此您在这里将错误的类型传递给您的泛型:

    const numberOfCakes = useSelector<ICakeState, ICakeState["numberOfCakes"]>(
      (state) => {
        console.log(state);
        return state.numberOfCakes;
      }
    );
    

    第二个问题是combineReducers 接受一个具有不同reducer 的对象,包括它们的名称,而不是一个数组,因此您需要将其更改为:

    export default createStore(
      combineReducers({cakeReducer}),
      composeWithDevTools()
    );
    
    export type RootState = ReturnType<typeof rootReducer>
    

    然后改变:

    const numberOfCakes = useSelector<RootState>(
      (state) => {
        console.log(state);
        return state.cakeReducer.numberOfCakes;
      }
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-29
      • 2017-08-11
      • 2017-12-08
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      相关资源
      最近更新 更多