无法从反应组件中的道具读取 属性
Cannot read property from props in react component
在 ChatRoom
组件中,我试图加载 2 个用户之间的聊天以呈现聊天用户的姓名。为了进行聊天,我正在启动 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));
};
当我尝试 console.log
ChatRoom
中的 currentChat
时,它会正确显示聊天。
currentChat:
messages: []
user1: {
_id: "5d1328a91e0e5320706cdabb",
name: "sarvar",
}
user2: {
_id: "5d131405ce36ce0ebcf76ae1",
name: "jalol makhmudov"
}
__v: 0
_id: "5d329aea3f34fe0b8c6cf336"
如果我渲染 currentChat._id
(请参阅 ChatRoom
中的 <h3>
元素),它会正确显示它。
但是如果我渲染 currentChat.user1.name
和 currentChat.user2.name
(参见 ChatRoom
中的 <h2>
元素),它会给出错误
TypeError: Cannot read property 'name' of undefined
解决方案
用更准确的形状初始化状态。
const initialState = {
currentChat: {
user1: {}
},
loadingCurrentChat: false,
};
如果您不能这样做,请在 JSX 中访问它之前像 currentChat.user1 && currentChat.user1.name
一样进行检查。
说明
getCurrentChat
是一个请求,这意味着获取数据需要时间。 React 不会等待请求完成进行渲染。我们定义 initialState
的原因之一是因为在请求完成时,React 使用 initialState
进行渲染。
在您的例子中,initialState 定义为,
const initialState = {
currentChat: {},
loadingCurrentChat: false,
};
在JavaScript中,当您定义一个空对象currentChat: {}
时,您可以毫无错误地访问它的直接子对象。因此 currentChat._id
是可访问的,但由于 currentChat.user1
是 undefined
,currentChat.user1.name
将抛出错误。
在 ChatRoom
组件中,我试图加载 2 个用户之间的聊天以呈现聊天用户的姓名。为了进行聊天,我正在启动 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));
};
当我尝试 console.log
ChatRoom
中的 currentChat
时,它会正确显示聊天。
currentChat:
messages: []
user1: {
_id: "5d1328a91e0e5320706cdabb",
name: "sarvar",
}
user2: {
_id: "5d131405ce36ce0ebcf76ae1",
name: "jalol makhmudov"
}
__v: 0
_id: "5d329aea3f34fe0b8c6cf336"
如果我渲染 currentChat._id
(请参阅 ChatRoom
中的 <h3>
元素),它会正确显示它。
但是如果我渲染 currentChat.user1.name
和 currentChat.user2.name
(参见 ChatRoom
中的 <h2>
元素),它会给出错误
TypeError: Cannot read property 'name' of undefined
解决方案
用更准确的形状初始化状态。
const initialState = {
currentChat: {
user1: {}
},
loadingCurrentChat: false,
};
如果您不能这样做,请在 JSX 中访问它之前像 currentChat.user1 && currentChat.user1.name
一样进行检查。
说明
getCurrentChat
是一个请求,这意味着获取数据需要时间。 React 不会等待请求完成进行渲染。我们定义 initialState
的原因之一是因为在请求完成时,React 使用 initialState
进行渲染。
在您的例子中,initialState 定义为,
const initialState = {
currentChat: {},
loadingCurrentChat: false,
};
在JavaScript中,当您定义一个空对象currentChat: {}
时,您可以毫无错误地访问它的直接子对象。因此 currentChat._id
是可访问的,但由于 currentChat.user1
是 undefined
,currentChat.user1.name
将抛出错误。