长话短说:我希望它在嵌套数组中加载对象,如果它不等于未定义但反应抛出类型错误
我有一个组件,它从父组件中获取道具。本质上,我有一个包含聊天信息的数组,当我尝试在这个子组件中访问它时,我得到了一些非常奇怪的行为。
例如,如果我控制台日志(props.conversations(,我会得到如下所示的数组:conversations[{host, members[{ username }], log[{ author, content, timestamp }]}]。
如果我控制台日志(props.conversations[0](生病,就会得到该数组中的第一个对象。但是如果我控制台日志(props.conversations[0].log(,我就会变得未定义。这很好,因为在开始时状态不会被定义或包含任何内容,所以我在代码 props.conversations[props.index].log[0] == null 中放置了一个如下所示的三元运算符? 但我得到的只是类型错误:无法读取三元函数中未定义的属性"日志"。
也许我没有正确理解这一点,或者它是如何反应功能的? 同样,如果它不等于未定义,我希望它在嵌套数组中加载对象。
非常感谢您的帮助。最重要的部分是朋友组件。我只显示其他的来显示正在传递的状态。
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]。所以你不会得到类型错误:无法读取三元函数中未定义的属性"日志"。