开发者问题收集

在三元组能够检查对象是否未定义之前,React 会针对未定义的对象抛出类型错误

2018-10-25
1976

长话短说:如果嵌套数组中的对象不等于 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>
    );
} 
};
3个回答

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

使用类似这样的方法:

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

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

Faheem
2018-10-25

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

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

此外,您可以转到以下链接查看沙盒运行示例。

沙盒链接作为示例,展示如何检查未定义

developerKumar
2018-10-25

嗨,首先检查您的 {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”。

Dipal
2018-10-25