在三进制可以检查对象是否未定义之前,react会为未定义的对象抛出类型错误

时间:2018-10-25 04:44:52

标签: javascript arrays node.js reactjs undefined

长故事简短:如果不等于undefined,但我想让它将对象加载到嵌套数组中,则反应抛出typeError

我有这个组件,它从父组件中获取道具。本质上,我有一个包含聊天信息的数组,当我尝试在此子组件中访问它时,我会得到一些非常奇怪的行为。

例如,如果我管理日志(props.conversations),则得到的数组如下所示:对话[{主机,成员[{用户名}],日志[{作者,内容,时间戳}]}]]。

如果我通过控制台日志(props.conversations [0])获取该数组中的第一个对象。但是,如果我管理日志(props.conversations [0] .log),则无法定义。那很好,因为一开始状态不会被定义或包含任何东西,所以我在代码props.conversations [props.index] .log [0] == null中放置了一个三元运算符,如下所示 但我得到的只是TypeError:无法在三元函数中读取未定义的属性“ log”。

也许我没有正确理解这一点,或者它如何反应功能? 同样,如果它不等于undefined,我希望它在嵌套数组中加载对象。

非常感谢您的帮助。最重要的部分是朋友组件。我只显示其他内容以显示正在传递的状态。

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>
    );
} 
};

3 个答案:

答案 0 :(得分:0)

在验证之前直接访问元素不是一个好主意。

使用类似这样的内容:

props.conversations[props.index] && props.conversations[props.index].log[0]

提示:用户对象分解和默认道具。

答案 1 :(得分:0)

您需要像这样对未定义进行比较:

{props.conversations[props.index].log[0] === undefined ?
        <div>undefined</div>
        :
        <div>defined!</div>
       }

此外,您可以转到下面的链接来查看沙箱运行示例。

Sandbox link for example to show how you should check for undefined

答案 2 :(得分:0)

您好,首先请检查您的{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:无法在三元函数中读取undefined的属性“ log”。