在三元组能够检查对象是否未定义之前,React 会针对未定义的对象抛出类型错误
长话短说:如果嵌套数组中的对象不等于 undefined,但 React 抛出了 typeError,我希望它能加载该对象
我有这个组件,它从父组件获取 props。本质上,我有一个包含聊天信息的数组,当我尝试在此子组件中访问它时,我得到了一些非常奇怪的行为。
例如,如果我控制台日志(props.conversations),我会得到如下所示的数组:对话[{host, members[{ username }], log[{ author, content, timestamp }]}]。
如果我控制台日志(props.conversations[0]),我会得到该数组中的第一个对象。但如果我控制台日志(props.conversations[0].log),我会得到未定义的。这很好,因为一开始状态不会被定义或包含任何内容,所以我在代码中放置了一个三元运算符,如下所示 props.conversations[props.index].log[0] == null ? 但我得到的只是 TypeError: Cannot read property 'log' of undefined at the ternary function.
也许我没有正确理解这一点,或者也许是 react 的功能? 再次,我希望它在嵌套数组中加载对象,如果它不等于未定义。
非常感谢您的帮助。最重要的部分是朋友组件。我只显示其他内容以显示正在传递的状态。
function Friends(props) {
console.log(props.conversations[props.index]);
return (
<div className="friend">
<img className="friendavatar" src={require("./static/bobby.jpg")}></img>
<div className="friendname">{props.username}</div>
<span className="iswatchingtitle"> is watching <strong>{props.watching}</strong></span>
<div className="friendchat" onClick={props.togglechat}>
{props.conversations[props.index].log[0] == null ?
<div>undefined</div>
:
<div>defined!</div>
}
</div>
</div>
)
}
社交组件
function Social(props) {
return (
<div>
<div className="userquickdash row">
<div className="usernamedash">{props.username}</div>
<div className="logout"><a href="/users/logout" onClick={props.fetchlogout}>logout</a></div>
</div>
<div>
<form className="search-form-flex" method="GET" action="/search">
<input className="user-search" id="search" type="search" placeholder=" Search users..." name="usersearch"></input>
</form>
</div>
<div className='friendchatcontainer' refs='friendchatcontainer'>
{/* Append friends from social bar state (props.friends). For each friend return appropriate object info to build Friends div using Friends(props) function above. */}
{props.friends.map(function(friend, index) {
// Shortens length of video title if length of string is over 48.
let friendWatching = function friendWatchingLengthSubstring() {
if (friend.watching.length > 57) {
let friendWatching = friend.watching.substring(0, 54) + '...';
return friendWatching;
} else {
friendWatching = friend.watching;
return friendWatching;
}
};
return (
<Friends username={friend.username}
watching={friendWatching()}
key={index}
index={index}
togglechat={props.togglechat}
conversations={props.conversations}
/>
)
})}
</div>
</div>
)
}
社交栏组件
class Socialbar extends Component {
constructor(props) {
super(props);
this.state = { isLoggedIn: (cookies.get('loggedIn')),
sidebarximgSrc: sidebarcloseimg,
sidebarStatus: 'open',
username: cookies.get('loggedIn'),
friends: friends,
users: {},
conversations: [],
};
}
// function to run when mongodb gets information that state has changed.
// test if the current state is equal to new object array.
// then do something.
appendFriends() {
}
componentDidMount() {
if (this.state.sidebarStatus === 'open') {
document.getElementsByClassName('maindash')[0].classList.add('maindashwide');
this.openSideBar();
} else {
document.getElementsByClassName('maindash')[0].classList.remove('maindashwide');
this.closeSideBar();
}
// check for user logged in cookie, if true fetch users.
if (this.state.isLoggedIn) {
this.fetchUsers();
}
this.getFriendConversations();
};
getFriendConversations() {
// build loop function that updates state for conversations based on length of friends array in state.
var conversationsArray = this.state.conversations;
for (var i = 0; i < friends.length; i++) {
console.log(aconversationbetweenfriends[i]);
conversationsArray.push(aconversationbetweenfriends[i]);
}
this.setState({conversations: conversationsArray});
}
render() {
let sidebar;
const isLoggedIn = this.state.isLoggedIn;
if (!isLoggedIn) {
sidebar = <Login />
} else {
sidebar = <Social username={this.state.username} friends={this.state.friends} fetchlogout={this.fetchlogout} togglechat={this.togglechat} conversations={this.state.conversations} />
}
return (
<div>
<div className="sidebar sidebar-open" ref="sidebar">
<div className="sidebarcontainer">
{sidebar}
</div>
</div>
<div className="sidebarx sidebarxopen" ref="sidebarx" onClick={this.toggleSideBar}>
<img className="sidebaropenimg" src={this.state.sidebarximgSrc} ref='sidebarximg'></img>
</div>
</div>
);
}
};
在验证之前直接访问元素并不是一个好主意。
使用类似这样的方法:
props.conversations[props.index] && props.conversations[props.index].log[0]
提示:用户对象解构和默认道具。
您需要像这样比较未定义:
{props.conversations[props.index].log[0] === undefined ?
<div>undefined</div>
:
<div>defined!</div>
}
此外,您可以转到以下链接查看沙盒运行示例。
嗨,首先检查您的 {props.index} 是否打印此值。如果正确,请尝试一下。
{
props.conversations[props.index] ?
props.conversations[props.index].log[0] ? <div>defined!</div>:<div>Undefined</div>
:
<div>Undefined</div>
}
这将检查 props.conversations[props.index] 是否已定义,然后仅尝试处理 props.conversations[props.index].log[0]。因此,您不会在三元函数中收到 TypeError:无法读取未定义的属性“log”。