【问题标题】:× TypeError: Cannot read property 'dishes' of undefined× TypeError: 无法读取未定义的属性“菜”
【发布时间】:2021-01-07 04:59:03
【问题描述】:

请帮忙!!

我使用 react 创建了一个 web 应用程序并将其与 node js 连接。

我需要将菜肴的状态传递给 DishDetail 组件,无论它是否在收藏夹中。 如果不是最喜欢的。我必须将其标记为收藏。 每当有人点击任何菜肴使其成为收藏夹时,就会在favorite collection 中添加一个条目,其中包含用户 ID 和菜肴 ID

但是每当一个新用户登录并尝试像第一次一样添加最喜欢的菜时。我在 遇到 ×TypeError: Cannot read property 'dishes' of undefined 的错误在 MainComponent.js 和 var favorites = props.favorites.favorites.dishes.map((dish) 声明FavoriteDish.js。

MainComponent.js

const DishWithId = ({match}) => {
      if(this.props.favorites.favorites!=null) {
        if(Array.isArray(this.props.favorites.favorites)) {
          this.props.favorites.favorites=this.props.favorites.favorites[0];
        }
      }
      
      return(
        (this.props.auth.isAuthenticated && !this.props.favorites.isLoading)
        ?
        <DishDetail dish={this.props.dishes.dishes.filter((dish) => dish._id === match.params.dishId)[0]}
          isLoading={this.props.dishes.isLoading}
          errMess={this.props.dishes.errMess}
          comments={this.props.comments.comments.filter((comment) => comment.dish === match.params.dishId)}
          commentsErrMess={this.props.comments.errMess}
          postComment={this.props.postComment}
          favorite={this.props.favorites.favorites.dishes.some((dish) => dish._id === match.params.dishId)}
          postFavorite={this.props.postFavorite}
          />
        :
        <DishDetail dish={this.props.dishes.dishes.filter((dish) => dish._id === match.params.dishId)[0]}
          isLoading={this.props.dishes.isLoading}
          errMess={this.props.dishes.errMess}
          comments={this.props.comments.comments.filter((comment) => comment.dish === match.params.dishId)}
          commentsErrMess={this.props.comments.errMess}
          postComment={this.props.postComment}
          favorite={false}
          postFavorite={this.props.postFavorite}
          />
      );
    } 
    <Route path="/menu/:dishId" component={DishWithId} />
    <PrivateRoute exact path="/favorites" component={() => <Favorites favorites {this.props.favorites} deleteFavorite={this.props.deleteFavorite} />} />

DishDetail.js

const DishDetail = (props) => {
    return <RenderDish dish={props.dish} favorite={props.favorite} postFavorite={props.postFavorite} />
}

function RenderDish({dish, favorite, postFavorite}) {
    return(
        <div className="col-12 col-md-5 m-1">
            <FadeTransform in 
                transformProps={{
                    exitTransform: 'scale(0.5) translateY(-50%)'
                }}>
                <Card>
                    <CardImg top src={baseUrl + dish.image} alt={dish.name} />
                    <CardImgOverlay>
                        <Button outline color="primary" onClick={() => favorite ? console.log('Already favorite') : postFavorite(dish._id)}>
                            {favorite ?
                                <span className="fa fa-heart"></span>
                                : 
                                <span className="fa fa-heart-o"></span>
                            }
                        </Button>
                    </CardImgOverlay>
                    <CardBody>
                        <CardTitle>{dish.name}</CardTitle>
                        <CardText>{dish.description}</CardText>
                    </CardBody>
                </Card>
            </FadeTransform>
        </div>
    );

}

FavoriteDish.js

    if (props.favorites.favorites) {
       if(Array.isArray(props.favorites.favorites))
          props.favorites.favorites=props.favorites.favorites[0];
       var favorites = props.favorites.favorites.dishes.map((dish) => {
         return (
             <div key={dish._id} className="col-12 mt-5">
                 <RenderMenuItem dish={dish} deleteFavorite={props.deleteFavorite} />
             </div>
         );
      });
   }

最喜欢的减速器

import * as ActionTypes from './ActionTypes';

export const favorites = (state = {
        isLoading: true,
        errMess: null,
        favorites: null
    }, action) => {
    switch(action.type) {
        case ActionTypes.ADD_FAVORITES:
            return {...state, isLoading: false, errMess: null, favorites: action.payload};

        case ActionTypes.FAVORITES_LOADING:
            return {...state, isLoading: true, errMess: null, favorites: null};

        case ActionTypes.FAVORITES_FAILED:
            return {...state, isLoading: false, errMess: action.payload, favorites: null};

        default:
            return state;
    }
}

ActionCreator.js

export const fetchFavorites = () => (dispatch) => {
    dispatch(favoritesLoading(true));

    const bearer = 'Bearer ' + localStorage.getItem('token');

    return fetch(baseUrl + 'favorites', {
        headers: {
            'Authorization': bearer
        },
    })
    .then(response => {
        if (response.ok) {
            return response;
        }
        else {
            var error = new Error('Error ' + response.status + ': ' + response.statusText);
            error.response = response;
            throw error;
        }
    },
    error => {
        var errmess = new Error(error.message);
        throw errmess;
    })
    .then(response => response.json())
    .then(favorites => dispatch(addFavorites(favorites)))
    .catch(error => dispatch(favoritesFailed(error.message)));
}

export const favoritesLoading = () => ({
    type: ActionTypes.FAVORITES_LOADING
});

export const favoritesFailed = (errmess) => ({
    type: ActionTypes.FAVORITES_FAILED,
    payload: errmess
});

export const addFavorites = (favorites) => ({
    type: ActionTypes.ADD_FAVORITES,
    payload: favorites
});

【问题讨论】:

  • 你确定this.props.favorites.favorites 是正确的吗?应该是this.props.favorites
  • 另外,您绝对不允许像在例如` this.props.favorites.favorites=this.props.favorites.favorites[0];` ...
  • 没有。这是正确的。一个是我最喜欢的,另一个是在 reducers 中创建的数组。
  • @AKX 我在那条线上没有遇到问题......即使删除那条线也没有解决我的问题。该声明是为了另一个目的
  • 你可能不会在这里遇到错误,但你不能在 React 领域改变 props,这会导致问题。

标签: javascript node.js reactjs


【解决方案1】:

从乔瓦尼·埃斯波西托那里得到想法。

我刚刚更改了这一行:- favorite={this.props.favorites.favorites.dishes.some((dish) =&gt; dish._id === match.params.dishId)}

对此:- favorite={this.props.favorites.favorites ? this.props.favorites.favorites.dishes.some((dish) =&gt; dish._id === match.params.dishId): false}

【讨论】:

    【解决方案2】:

    Ciao,你可以修改这一行(DishWithId):

    (this.props.auth.isAuthenticated && !this.props.favorites.isLoading)
    

    与:

    (this.props.auth.isAuthenticated && !this.props.favorites.isLoading && this.props.favorites.favorites)
    

    这一行(在 FavoriteDish.js 中):

    var favorites = props.favorites.favorites.dishes.map((dish)...
    

    与:

    if (props.favorites.favorites) {var favorites = props.favorites.favorites.dishes.map((dish)...}
    

    【讨论】:

    • 仍然出现 TypeError: Cannot read property 'dishes' of undefined
    • 是的,我忘记在其他favoritesswitch(action.type))上添加相同的初始值。我更新了我的答案。
    • 还是一样 ;(
    • 在控制台中获取此信息 - 收藏夹:errMess:“无法读取未定义的属性‘菜肴’”收藏夹:{dishes: Array(0)} isLoading: false
    • 好的,所以仍然只有操作ADD_FAVORITES。如果您登录action.payload,您会看到什么?
    【解决方案3】:

    检查收藏夹中的条件,以防收藏夹未定义。它会在那里自动发送 false...

    favorite={this.props.favorites.favorites ? this.props.favorites.favorites.dishes.some((dish) => dish._id === match.params.dishId): false}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      • 2019-08-19
      • 1970-01-01
      相关资源
      最近更新 更多