React组件绑定this后,函数返回<li>时this.state未定义求助
问题原因及解决方案
嘿,我来帮你分析一下这个问题~
你遇到的核心问题是:在constructor里初始化state时调用了typeContactGetter,但此时this.state还没完成赋值。
具体来说,当你在constructor里写this.state = { ..., familyContacts: this.typeContactGetter("Family") }的时候,整个state对象还在构建过程中,还没有被赋值给this.state。这时候typeContactGetter内部尝试访问this.state,自然会得到undefined。
另外还有个小建议:尽量不要把JSX元素存在state里,React的设计理念是让state存储数据,UI渲染基于数据动态生成,把JSX存在state里既不符合最佳实践,也容易引发这类状态访问的问题。
下面给你两个可行的解决方案:
方案一:移到componentDidMount中初始化
把依赖state的逻辑放到组件挂载后的生命周期函数里,此时state已经完全初始化,就能正常访问了:
class ContactType extends Component { constructor(props) { super(props); this.state = { date: new Date(), hiddenList: false, // 先初始化空数组 familyContacts: [], friendContacts: [] }; // 绑定函数到this this.typeContactGetter = this.typeContactGetter.bind(this); } componentDidMount() { // 组件挂载后再调用函数更新状态 this.setState({ familyContacts: this.typeContactGetter("Family"), friendContacts: this.typeContactGetter("Friend") }); } typeContactGetter(type) { // 这里可以正常访问this.state了 return this.props.contacts .filter(contact => contact.type === type) .map(contact => ( <li key={contact.id} className={this.state.hiddenList ? 'hidden' : ''}> {contact.name} </li> )); } // 其他组件逻辑... }
方案二:直接在render中调用函数(推荐)
既然typeContactGetter是用来生成渲染用的列表项,不如直接在render里调用它,这样每次渲染都会基于最新的state生成UI,完全避免状态访问的问题,也符合React的最佳实践:
class ContactType extends Component { constructor(props) { super(props); this.state = { date: new Date(), hiddenList: false }; this.typeContactGetter = this.typeContactGetter.bind(this); } typeContactGetter(type) { return this.props.contacts .filter(contact => contact.type === type) .map(contact => ( <li key={contact.id} className={this.state.hiddenList ? 'hidden' : ''}> {contact.name} </li> )); } render() { return ( <div className="contact-type"> <h3>Family Contacts</h3> <ul>{this.typeContactGetter("Family")}</ul> <h3>Friend Contacts</h3> <ul>{this.typeContactGetter("Friend")}</ul> </div> ); } }
这样修改后,你在<li>里访问this.state.hiddenList就不会再出现undefined的情况啦~
内容的提问来源于stack exchange,提问作者clusterBuddy
相关产品推荐
相关产品推荐

