【问题标题】:Cannot read property from props in react component无法从反应组件中的道具读取属性
【发布时间】:2019-11-29 01:44:21
【问题描述】:

ChatRoom 组件中,我正在尝试加载两个用户之间的聊天以呈现聊天用户的姓名。为了聊天,我启动了getCurrentChat 功能。

ChatRoom 组件

// importing everything
import { getCurrentChat } from '../../actions/chatActions';

class ChatRoom extends Component {
   componentDidMount() {
      // loading chat between 2 people
      this.props.getCurrentChat(this.props.match.params.chatId); 
   };

   render() {
      const { loadingCurrentChat } = this.props.chat;
      console.log(this.props.chat.currentChat);

      return (
         <div className="container">
            {loadingCurrentChat ? <Spinner /> : (
               <div className="row">
                  <h3>ChatId: {this.props.chat.currentChat._id}</h3>

                  <h2>Chat between {this.props.chat.currentChat.user1.name} и {this.props.chat.currentChat.user2.name}</h2>
               </div>
            )}
         </div>
       )
   }
}

const mapStateToProps = (state) => ({
   auth: state.auth,
   chat: state.chat
});

export default connect(mapStateToProps, { getCurrentChat })(withRouter(ChatRoom));

chatActions.js

export const getCurrentChat = (chatId) => (dispatch) => {
  dispatch(setLoadingCurrentChat());
  axios.get(`/chat/${chatId}`)
    .then(res =>
      dispatch({
        type: GET_CURRENT_CHAT,
        payload: res.data
      })
    )
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err
      })
    );
};

chatReducer.js

// importing everything
const initialState = {
  currentChat: {},
  loadingCurrentChat: false,
};

export default function (state = initialState, action) {
  switch (action.type) {
    case SET_LOADING_CURRENT_CHAT:
      return {
        ...state,
        loadingCurrentChat: true
      }
    case GET_CURRENT_CHAT:
      return {
        ...state,
        currentChat: action.payload,
        loadingCurrentChat: false
      }
  }
}

我处理来自chatActions.js 的请求的服务器文件 - chatController.js

// requiring everything

exports.getCurrentChat = (req, res) => {
  const chatId = req.params.chatId;
  Chat.findById(chatId)
    .populate('user1')
    .populate('user2')
    .exec()
    .then(chat => res.json(chat))
    .catch(err => res.status(400).json(err));
  };

当我在ChatRoom 中尝试console.logcurrentChat 时,它会正确显示聊天。

currentChat:

     messages: []
     user1: {
        _id: "5d1328a91e0e5320706cdabb", 
        name: "sarvar", 
     }
     user2: {
        _id: "5d131405ce36ce0ebcf76ae1", 
        name: "jalol makhmudov"
      }
     __v: 0
     _id: "5d329aea3f34fe0b8c6cf336"

如果我渲染currentChat._id(参见ChatRoom 中的&lt;h3&gt; 元素),它会正确显示它。

但如果我渲染 currentChat.user1.namecurrentChat.user2.name(请参阅 ChatRoom 中的 &lt;h2&gt; 元素),则会出现错误

TypeError: Cannot read property 'name' of undefined

【问题讨论】:

  • 打印会得到什么结果 -- this.props.chat.currentChat.user1
  • 如果我 console.log(this.props.chat.currentChat.user1) 我得到了 user1 对象:name: "sarvar" _id: "5d1328a91e0e5320706cdabb"

标签: node.js reactjs react-redux axios react-props


【解决方案1】:

解决方案

用更精确的形状初始化状态。

const initialState = {
  currentChat: {
    user1: {}
  },
  loadingCurrentChat: false,
};

如果您不能这样做,请在 JSX 中访问它之前进行检查,例如 currentChat.user1 &amp;&amp; currentChat.user1.name

说明

getCurrentChat 是一个请求,这意味着获取数据需要时间。 React 不会等待请求完成进行渲染。我们定义initialState 的原因之一是因为在请求完成时,React 使用initialState 进行渲染。

在您的情况下,initialState 定义为,

const initialState = {
  currentChat: {},
  loadingCurrentChat: false,
};

在 JavaScript 中,当您定义一个空对象 currentChat: {} 时,您可以访问其直接子对象而不会出现任何错误。因此currentChat._id 是可以访问的,但是由于currentChat.user1undefinedcurrentChat.user1.name 会抛出一个错误。

【讨论】:

    猜你喜欢
    • 2020-06-05
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 2021-11-15
    • 2021-03-16
    • 2018-01-21
    相关资源
    最近更新 更多