在React Redux中实现的抓取操作返回:“无法读取未定义的属性'title'”

时间:2019-08-06 14:38:37

标签: javascript reactjs redux react-redux axios

我想实现一个通过ID获取项目的操作,因此我创建了fetchItemAction(),如下所示:

export const fetchItemAction = () => (dispatch) => {
  dispatch({
    type: FETCH_ITEM_REQUEST,
  });
  return axios.get(`${url}/notes/5d4724cd62087b0e141f75a4`)
    .then(({ data }) => {
      console.log(data);
      dispatch({
        type: FETCH_ITEM_SUCCESS,
        data,
      });
    })
    .catch((error) => {
      dispatch({
        type: FETCH_ITEM_FAILURE,
      });
    });
};

然后,我尝试在化简版的State中设置item字段:

const initialState = {
  isAuthenticated: false,
  user: {},
};

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case FETCH_ITEM_REQUEST:
        return {
            ...state,
            isLoading: true,
        };
        case FETCH_ITEM_SUCCESS:
        return {
            ...state,
            item: action.data,
            isLoading: false,
        };
    }
};

然后,我尝试在Details组件中获取这些数据:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchItemAction } from 'actions/actions';

class Details extends Component {
  componentDidMount() {
    const { fetchItem } = this.props;
    fetchItem();
  }

  render() {
    const { item, isLoading } = this.props;
    return (
      <>
        {console.log(item)} 
        {/* <p>{item.title}</p> */}
      </>
    );
  }
}

const mapStateToProps = ({ item, isLoading }) => ({ item, isLoading });

const mapDispatchToProps = dispatch => ({
  fetchItem: () => dispatch(fetchItemAction()),
});

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

结果,我在控制台中获取以下数据: Console

除了两个undefinded之外,结果看起来还不错,因为后端有正确的响应。

但是,当我尝试取消注释<p>item.title</p>中的Details.js行时,应用程序崩溃:

TypeError: Cannot read property 'title' of undefined

我也正确地实现了fetchItemsAction()addItemAction()deleteItemAction(),它们非常相似,但是我不知道fetchItemAction()出了什么问题。

1 个答案:

答案 0 :(得分:3)

这是一个异步问题。装入组件时将调用componentDidMount。然后,您正在呼叫fetch。因此,在您的第一个渲染中,item是未定义的。返回数据后,将使用item数据再次触发渲染。

因此,只需检查是否定义了item

render() {
  const { item, isLoading } = this.props;
  return (
    <>
      {console.log(item)} 
      {item && <p>{item.title}</p>}
    </>
  );
}