Cannot change parent's state from child

reactjs

324 观看

1回复

8 作者的声誉

Getting

TypeError: Object doesn't support property or method 'setState' 

while trying to set parent's state from a child.

parent function:

setSubject(id){
 console.log(id);
 this.setState({
     currentSubject: id
});
<Subjects authToken = {this.state.authToken} subjects = {this.state.subjects} setSubject = {this.setSubject} />

child function:

const listSubjects = this.props.subjects.map(subject => {
        return(<div key={subject.id}>
                    <li  data-toggle="collapse" data-target={"#" + subject.id}>{subject.title}</li>
                    <div id={subject.id} className="collapse">
                        <ul className="subject-features-list">
                            <li onClick={() => this.props.setSubject(subject.id)}>Egzamino programa</li>
                            <li>Egzaminai pagal metus</li>
                        </ul>
                    </div>
                </div>

What am I doing wrong?

作者: Donatas Jarmalovicius 的来源 发布者: 2017 年 12 月 27 日

回应 1


1

446 作者的声誉

决定

Simplest Solution:

const newSetSubject= this.setSubject.bind(this)
<Subjects authToken = {this.state.authToken} subjects = {this.state.subjects} setSubject = {this.newSetSubject} />

Why you have to do this?

this refers to the immediate scope of the function or class whose method you are invoking, in the particular case you took the setSubject method from some class and gave it to another class or function to call at its own it.

At the time of invokation, as per the implementation ofsetSubject, it expects that the current scope(this will be the scope of the child function in your case) has the setState method.

So the gist of the problem is the scope of this is refering to the scope of child function.

Consider the example below:

class PersonComponent {
  age = 21 //default case
  render() {
    return <div> Person's age is {this.props.getAge()}</div>
  } 
 }

Case 1:

class Person {
  name = "John Doe"

  age  = 29
  getAge() {
    return this.a;
  }
  render() {
    return <PersonComponent getAge={this.getAge} />
  }
 }

In this case result will be 21, because in the scope of the PersonComponent, the age is set at 21.

Case 2:

class Person {
  name = "John Doe"

  age  = 29
  getAge() {
    return this.a;
  }
  render() {
    return <PersonComponent getAge={this.getAge.bind(this)} />
  }
 }

In this case, the result will be Person's age is 29, because by using bind you explicity created a new method which has pre-defined scope to use.

作者: nirbhaygp 发布者: 2017 年 12 月 27 日
32x32