“react-redux”无法读取未定义的属性。

huangapple go评论85阅读模式
英文:

react-redux Cannot read properties of undefined

问题

在这段代码中,我使用了 react-redux 和 react-router。react-redux 的版本比较旧,但我想知道在这段代码中(指的是 react-redux 和 react-router 的这个版本)我哪里出错了。我试图在 main.jsx 中获取 ingredients,然后在 OrderSummary 组件中使用它,但是我遇到了以下错误:

  • 无法读取未定义的属性,
  • 未找到状态。

GitHub 仓库链接

main.jsx:

import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducer from "./store/reducer";

export default function Main(props) {
  const store = createStore(
    reducer /* preloadedState, */,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  );

  return (
    <Provider store={store}>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<Layout />} >
            <Route index element={<App />} />
            <Route
              path="/burger-builder/order-page"
              exact
              element={
                <OrderSummary
                  ingredients={props.ingredients}
                  totalPrice={props.totalPrice}
                />
              }
            />
            <Route path="*" element={<NoPage />} />
          </Route>
        </Routes>
      </BrowserRouter>
    </Provider>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Main />);

BurgerBuilder.jsx:

import * as actionTypes from "../../store/action";
import { connect } from "react-redux";

function BurgerBuilder(props) {
  return (
    <>
      <Burger ingredients={props.ings} />
      <BurgerControls
        addIngredients={props.onIngredientAdded}
        removeIngredients={props.onIngredientRemoved}
        totalprice={props.totalPrice}
        disabled={disableButton}
      />
    </>
  );
}

const mapStateToProps = (state) => {
  return {
    ings: state.ingredients,
    price: state.totalPrice,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    onIngredientAdded: (ingName) =>
      dispatch({ type: actionTypes.ADD_INGREDIENT, ingredientName: ingName }),
    onIngredientRemoved: (ingName) =>
      dispatch({
        type: actionTypes.REMOVE_INGREDIENT,
        ingredientName: ingName,
      }),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(BurgerBuilder);

部分内容

reducer.js:

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case actionTypes.ADD_INGREDIENT:
            return {
                ...state,
                ingredients: {
                    ...state.ingredients,
                    [action.ingredientName]: state.ingredients[action.ingredientName] + 1
                },
                totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]
            };
英文:

In this Code, I use react-redux and react-router. the react-redux version is old but I want to know where I went wrong in this piece of code (in this version of react-redux and react-router I meant).
I try to get ingredients in main.jsx and use it in OrderSummary Component but I got errors like:

  • Cannot read properties of undefined,
  • state not found.

github repository

main.jsx:

import ReactDOM from &quot;react-dom/client&quot;;
import { BrowserRouter, Routes, Route } from &quot;react-router-dom&quot;;
import { Provider } from &quot;react-redux&quot;;
import { createStore } from &quot;redux&quot;;
import reducer from &quot;./store/reducer&quot;;

export default function Main(props) {
  const store = createStore(
    reducer /* preloadedState, */,
    window.__REDUX_DEVTOOLS_EXTENSION__ &amp;&amp; window.__REDUX_DEVTOOLS_EXTENSION__()
  );

  return (
    &lt;Provider store={store}&gt;
      &lt;BrowserRouter&gt;
        &lt;Routes&gt;
          &lt;Route path=&quot;/&quot; element={&lt;Layout /&gt;}&gt;
            &lt;Route index element={&lt;App /&gt;} /&gt;
            &lt;Route
              path=&quot;/burger-builder/order-page&quot;
              exact
              element={
                &lt;OrderSummary
                  ingredients={props.ingredients}
                  totalPrice={props.totalPrice}
                /&gt;
              }
            /&gt;
            &lt;Route path=&quot;*&quot; element={&lt;NoPage /&gt;} /&gt;
          &lt;/Route&gt;
        &lt;/Routes&gt;
      &lt;/BrowserRouter&gt;
    &lt;/Provider&gt;
  );
}

const root = ReactDOM.createRoot(document.getElementById(&quot;root&quot;));
root.render(&lt;Main /&gt;);

BurgerBuilder.jsx:

import * as actionTypes from &quot;../../store/action&quot;;
import { connect } from &quot;react-redux&quot;;

function BurgerBuilder(props) {
return (
    &lt;&gt;
      &lt;Burger ingredients={props.ings} /&gt;
      &lt;BurgerControls
        addIngredients={props.onIngredientAdded}
        removeIngredients={props.onIngredientRemoved}
        totalprice={props.totalPrice}
        disabled={disableButton}
      /&gt;
    &lt;/&gt;
  );
}

const mapStateToProps = (state) =&gt; {
  return {
    ings: state.ingredients,
    price: state.totalPrice,
  };
};

const mapDispatchToProps = (dispatch) =&gt; {
  return {
    onIngredientAdded: (ingName) =&gt;
      dispatch({ type: actionTypes.ADD_INGREDIENT, ingredientName: ingName }),
    onIngredientRemoved: (ingName) =&gt;
      dispatch({
        type: actionTypes.REMOVE_INGREDIENT,
        ingredientName: ingName,
      }),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(BurgerBuilder);

part of

reducer.js:

const reducer = (state = initialState, action) =&gt; {
    switch (action.type) {
        case actionTypes.ADD_INGREDIENT:
            return {
                ...state,
                ingredients: {
                    ...state.ingredients,
                    [action.ingredienName]: state.ingredients[action.ingredientName] + 1
                },
                totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]
            };

答案1

得分: 0

在你的 Main 组件中,你正在传递 props.ingredientsprops.totalPriceOrderSummary,但是在 Main 中未定义 props —— 当你使用 root.render(<Main />); 渲染 Main 时没有传递任何内容。

要解决这个问题,你可以像你在 BurgerBuilder 中做的那样,将 OrderStatus 连接到 Redux 存储:

function OrderSummary(props) {
    // 访问映射的 props
    const { ingredients, totalPrice } = props;

    // ...
};

const mapStateToProps = (state) => {
    return {
        ingredients: state.ingredients,
        totalPrice: state.totalPrice,
    };
};

export default connect(mapStateToProps)(OrderSummary);

然后,在 Main 中,渲染 OrderSummary 时不需要使用 props

<Route path="/burger-builder/order-page" exact element={<OrderSummary />} />

此外,在你的 reducer 中有一个拼写错误。你在 ADD_INGREDIENT 情况下写成了 action.ingredienName 而不是 action.ingredientName。以下是修复后的 reducer.js:

case actionTypes.ADD_INGREDIENT:
    return {
        ...state,
        ingredients: {
            ...state.ingredients,
            [action.ingredientName]: state.ingredients[action.ingredientName] + 1
        },
        totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]
    };
英文:

In your Main component, you're passing props.ingredients and props.totalPrice to OrderSummary, but props is not defined in Main -- you don't pass any when you render Main with root.render(&lt;Main /&gt;);.

To get around this, you can connect OrderStatus to the Redux store like you do with BurgerBuilder:


function OrderSummary(props) {
    // access mapped props
    const { ingredients, totalPrice } = props;

    // ...
};

const mapStateToProps = (state) =&gt; {
    return {
        ingredients: state.ingredients,
        totalPrice: state.totalPrice,
    };
};

export default connect(mapStateToProps)(OrderSummary);

Then, in Main, render OrderSummary without props:

&lt;Route path=&quot;/burger-builder/order-page&quot; exact element={&lt;OrderSummary /&gt;} /&gt;

Also, there's a typo in your reducer. You wrote action.ingredienName instead of action.ingredientName in the ADD_INGREDIENT case. Here's the fixed reducer.js:

case actionTypes.ADD_INGREDIENT:
    return {
        ...state,
        ingredients: {
            ...state.ingredients,
            [action.ingredientName]: state.ingredients[action.ingredientName] + 1
        },
        totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]
    };

huangapple
  • 本文由 发表于 2023年5月21日 21:32:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76300164.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定