【问题标题】:Uncaught TypeError: Cannot read property 'state or props' of undefined未捕获的类型错误:无法读取未定义的属性“状态或道具”
【发布时间】:2017-01-23 00:49:19
【问题描述】:

所以我开始将我的应用程序从 ES2015 转换为使用 React 的 ES6。

我有一个父类和一个像这样的子类,

export default class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            code: ''
        };
    }

    setCodeChange(newCode) {
        this.setState({code: newCode});
    }


    login() {
        if (this.state.code == "") {
            // Some functionality
        }
    }

    render() {
        return (
            <div>
                <Child onCodeChange={this.setCodeChange} onLogin={this.login} />
            </div>
        );
    }
}

儿童班,

export default class Child extends Component {
    constructor(props) {
        super(props);
    }

    handleCodeChange(e) {
        this.props.onCodeChange(e.target.value);
    }

    login() {
        this.props.onLogin();
    }

    render() {
        return (
            <div>
                <input name="code" onChange={this.handleCodeChange.bind(this)}/>
            </div>
            <button id="login" onClick={this.login.bind(this)}>
        );
    }
}

Child.propTypes = {
    onCodeChange: React.PropTypes.func,
    onLogin: React.PropTypes.func
};

但是这会导致以下错误,

this.state 未定义

指的是,

if (this.state.code == "") {
    // Some functionality
}

知道是什么原因造成的吗?

【问题讨论】:

标签: reactjs ecmascript-6 es6-class


【解决方案1】:

你可以使用箭头函数来绑定你的函数。您需要在子组件和父组件中绑定函数。

家长:

export default class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            code: ''
        };
    }

    setCodeChange = (newCode) => {
        this.setState({code: newCode});
    }


    login = () => {
        if (this.state.code == "") {
            // Some functionality
        }
    }

    render() {
        return (
            <div>
                <Child onCodeChange={this.setCodeChange} onLogin={this.login} />
            </div>
        );
    }
}

儿童

export default class Child extends Component {
    constructor(props) {
        super(props);
    }

    handleCodeChange = (e) => {
        this.props.onCodeChange(e.target.value);
    }

    login = () => {
        this.props.onLogin();
    }

    render() {
        return (
            <div>
                <input name="code" onChange={this.handleCodeChange}/>
            </div>
            <button id="login" onClick={this.login}>
        );
    }
}

Child.propTypes = {
    onCodeChange: React.PropTypes.func,
    onLogin: React.PropTypes.func
};

还有其他方法可以绑定函数,例如您正在使用的方法,但您也需要为父组件执行此操作,如 &lt;Child onCodeChange={this.setCodeChange.bind(this)} onLogin={this.login.bind(this)} /&gt;

或者你可以在构造函数中指定绑定为

家长:

constructor(props) {
    super(props);
    this.state = {
        code: ''
    };
 this.setCodeChange = this.setCodeChange.bind(this);
 this.login = this.login.bind(this);
}

儿童

constructor(props) {
    super(props);
    this.handleCodeChange = this.handleCodeChange.bind(this);
    this.login = this.login.bind(this);
}

【讨论】:

  • 我已经评论了一个解释绑定功能的骗子的链接,为什么还要添加另一个基本上说完全相同的答案?
  • @ivarni 我之前没有看到你发表评论。我读了这个问题并回答了。
  • @ivarni 是的,您可能是对的,这是重复的,但我在父母和孩子身上都尝试过的绑定不起作用。因此,为什么我提出来看看是否有更好的方法。正如我认为的箭头函数很管用。
  • @ShubhamKhatri 如果我使用绑定方法,在渲染函数中调用绑定有什么问题吗?
  • 没有什么错误,但它效率低下,因为您将在每次渲染时创建新的函数对象
【解决方案2】:

我同意@Shubham Kathri 提供的所有不同解决方案,但渲染中的直接绑定除外。

不建议你直接在 render 中绑定你的函数。建议您始终在构造函数中绑定它,因为如果您直接在渲染中进行绑定,那么每当您的组件渲染时,Webpack 都会在捆绑文件中创建一个新的函数/对象,因此 Webpack 捆绑文件的大小会增加。由于许多原因,您的组件会重新渲染,例如:执行 setState 但如果您将它放在构造函数中,它只会被调用一次。

不推荐以下实现

<Child onCodeChange={this.setCodeChange.bind(this)} onLogin={this.login.bind(this)} />

始终在构造函数中执行,并在需要的地方使用 ref

constructor(props){
  super(props);
  this.login = this.login.bind(this);
  this.setCodeChange = this.setCodeChange.bind(this);
}

<Child onCodeChange={this.setCodeChange} onLogin={this.login} />

如果您使用的是 ES6,则不需要手动绑定,但如果您愿意,可以。如果您想避免与范围相关的问题和手动函数/对象绑定,可以使用箭头函数。

抱歉,如果我在手机中回答任何错别字

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2020-05-16
    • 2021-12-22
    • 2015-01-06
    • 2017-07-26
    相关资源
    最近更新 更多