为什么 useSelector 总是返回未定义?使用 React.js + Redux 工具包 + Redux Persist

0 reactjs redux-persist redux-toolkit

“我正在建造一个小型计算器。我试图在本地存储每个输入的数据。我的方法是将 redux 工具包与 redux-persist 结合起来。一切似乎都工作正常,我没有收到任何错误。我的商店正在更新并持续刷新。然而,在使用 useSelector 时,它总是返回为未定义,使用 redux devtools 我可以看到我试图获取的值存在。

Main.js(入口点)

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "react-redux";
import { store } from "./store/store";
import { PersistGate } from "redux-persist/integration/react";
import "bootstrap/dist/css/bootstrap.min.css";
import "./index.css";
import { persistStore } from "redux-persist";

let persistor = persistStore(store);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <App />
      </PersistGate>
    </Provider>
  </React.StrictMode>
); 
Run Code Online (Sandbox Code Playgroud)

roiCalculationSlice.jsx

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  shifts: 0,
  rate: 0,
  machines: 0,
  numberOfDaysPerWeek: 0,
  numberOfWeeksPerYear: 0,
};

export const roiCalculationSlice = createSlice({
  name: "roi",
  initialState,
  reducers: {
    shiftsReducer: (state, action) => {
      state.shifts = action.payload.shifts;
    },
    hoursReducer: (state, action) => {
      state.hoursPerShift = action.payload.hours;
    },
    rateReducer: (state, action) => {
      console.log(action.payload, "payload");
      state.rate = action.payload;
    },
    daysReducer: (state, action) => {
      state.numberOfDaysPerWeek = action.payload.numberOfDaysPerWeek;
    },
    weeksReducer: (state, action) => {
      state.numberOfWeeksPerYear = action.payload.numberOfWeeksPerYear;
    },
    machineReducer: (state, action) => {
      state.machines = action.payload.machines;
    },
  },
});


// Action creators are generated for each case reducer function
export const {
  rateReducer,
  shiftsReducer,
  hoursReducer,
  weeksReducer,
  machineReducer,
} = roiCalculationSlice.actions;

export default roiCalculationSlice.reducer;
Run Code Online (Sandbox Code Playgroud)

FirstStep.jsx(组件)

import { useEffect, useState } from "react";
import { NavLink } from "react-router-dom";
import CustomButton from "./../components/buttons/CustomButton";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import Logo from "../assets/transor-modified.png";
import { useDispatch, useSelector } from "react-redux";
import "./firstStep.css";
import {
  hoursReducer,
  rateReducer,
  shiftsReducer,
} from "../store/features/roiCalculationSlice";

function FirstStep() {
  const dispatch = useDispatch();
  // This useSelector returns undefined
  const storeRate = useSelector((store) => {
    store.roi.rate;
  });
  // This useSelector returns undefined
  console.log(storeRate, "useSelector result");

  const [shifts, setshifts] = useState(0);
  const [days, setDays] = useState(0);
  const [rate, setRate] = useState(0);

  const onRateChange = (e) => {
    dispatch(rateReducer(e.currentTarget.value));
  };

  return (
    <Container>
      <Row className="justify-content-end">
        <Col xs={3}>
          <img className="img-fluid" src={Logo} alt="transor logo" />
        </Col>
      </Row>
      <Row>
        <Col>
          <h1 className="firststep-title">STEP 1 </h1>
        </Col>
      </Row>
      <Row>
        <Col>
          <label className="firststep-label" htmlFor="shifts">
            NUMBER OF SHIFTS
          </label>
          <br />
          <input
            onChange={(e) => {
              setshifts(e.currentTarget.value);
            }}
            className="calculation-input"
            type="number"
            id="shifts"
            name="shifts"
          />
        </Col>
      </Row>
      <Row>
        <Col>
          <label className="firststep-label" htmlFor="shifts">
            $ PER HOUR
          </label>
          <br />
          <input
            className="calculation-input"
            type="text"
            onChange={(e) => setRate(e.currentTarget.value)}
          />
        </Col>
      </Row>
      <Row>
        <Col>
          <label className="firststep-label" htmlFor="shifts">
            HOURS PER DAY
          </label>
          <br />
          <input
            onChange={(e) => {
              setDays(e.currentTarget.value);
            }}
            className="calculation-input"
            type="number"
            id="shifts"
            name="shifts"
          />
        </Col>
      </Row>

      <Row>
        <Col>
          <CustomButton className="custom-button-home">
            <NavLink className="custom-button-home" to="/secondstep">
              Next
            </NavLink>
          </CustomButton>
        </Col>
      </Row>
      <Row>
        <Col>
          <CustomButton className="custom-button-home ">
            <NavLink className="custom-button-home" to="/getstarted">
              Back
            </NavLink>
          </CustomButton>
        </Col>
      </Row>
    </Container>
  );
}

export default FirstStep;

Run Code Online (Sandbox Code Playgroud)

我的 redux devtools + console.log 结果的图像

小智 6

您需要从 useSelector 返回值。您可以尝试以下方法

useSelector((store) => {
   return store.roi.rate;
});
Run Code Online (Sandbox Code Playgroud)