【问题标题】:Update React Grandparent State from onClick in Grandchild从孙子中的 onClick 更新反应祖父母状态
【发布时间】:2018-01-13 09:56:39
【问题描述】:

我正在尝试使用 react 创建一个元素列表,并在单击单个元素时更新此列表的父级的状态。

整个容器是 App.jsx(祖父母)

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      selectedClass: null,
      query: "cs 2110"
    }

    this.handleSelectClass.bind(this);
  }

  handleSelectClass(classId) {
    console.log(classId);

    //get the id of the course and get full course details
    Meteor.call('getCourseById', classId, function(error, result) {
      if (!error) {
        console.log(this.state); 
        this.setState({selectedClass: result, query: ""}, function() {
          console.log(this.state.selectedClass);
          console.log(this.state.query);
        });
      } else {
        console.log(error)
      }
    });
  }

  //check if a class is selected, and show a coursecard only when one is.
  renderCourseCard() {
    var toShow = <div />; //empty div
    if (this.state.selectedClass != null) {
      toShow = <CourseCard course={this.state.selectedClass}/>;
    }
    return toShow;
  }

  render() {
    return (
      <div className="container">
        <header>
          <h1>Todo List</h1>
        </header>
        <div className='row'>
          <input />
          <Results query={this.state.query} clickFunc={this.handleSelectClass}/>
        </div>
        <div className='row'>
          <div className="col-md-6">
            {this.renderCourseCard()}
          </div>
          <div className="col-md-6 panel-container fix-contain">
            <Form courseId="jglf" />
          </div>
        </div>
      </div>
    );
  }
}

父容器是Results.jsx

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

  renderCourses() {
    if (this.props.query != "") {
      return this.props.allCourses.map((course) => (
        //create a new class "button" that will set the selected class to this class when it is clicked.
        <Course key={course._id} info={course} handler={this.props.clickFunc}/>
      ));
    } else {
      return <div />;
    }
  }

  render() {
    return (
      <ul>
        {this.renderCourses()}
      </ul>
    );
  }
}

课程列表项是孙子组件

export default class Course extends Component {
  render() {
    var classId = this.props.info._id;
    return (
      <li id={classId} onClick={() => this.props.handler(classId)}>{this.props.info.classFull}</li>
    );
  }
}

我按照Reactjs - How to pass values from child component to grand-parent component?这里的建议传递了一个回调函数,但回调仍然无法识别祖父母的状态。即使 classId 正确,App.jsx 中的 console.log(this.state) 也会返回 undefined,并且错误显示“在传递调用 'getCourseById' 的结果时出现异常:TypeError: this.setState is not a function”

这是绑定的问题吗?我在没有 Course 作为自己的组件的情况下尝试过这个,并且遇到了同样的问题。

【问题讨论】:

    标签: javascript reactjs callback state


    【解决方案1】:

    快速浏览代码。我可以看到问题之一在这里。即使你已经将你的函数绑定到你的组件,你正在使用一个流星调用,它将结果范围限定在它自己的函数范围内,这意味着它将无法访问 this.setState。您可以使用粗箭头函数来解决此问题,但您需要确保您使用的是 ES6。

    Meteor.call('getCourseById', classId, function(error, result) => {
      if (!error) {
        console.log(this.state); 
        this.setState({selectedClass: result, query: ""}, function() {
          console.log(this.state.selectedClass);
          console.log(this.state.query);
        });
      } else {
        console.log(error)
      }
    });
    

    到

    Meteor.call('getCourseById', classId, (error, result) => {
      if (!error) {
        console.log(this.state); 
        this.setState({selectedClass: result, query: ""}, () => {
          console.log(this.state.selectedClass);
          console.log(this.state.query);
        });
      } else {
        console.log(error)
      }
    });
    

    您还错误地将函数绑定到您的组件。

    this.handleClassSubmit = this.handleClassSubmit.bind(this);
    

    【讨论】:

    • 我尝试了这些更改,但我仍然在日志中得到未定义的 this.state(虽然没有错误,但流星调试正在打印“无消息”)。我正在使用最新的 Meteor 版本,所以我相信它正在运行 es6 - 我看到安装了 es5-shim 和 ecmascript@0.8.1 包。
    • 刚刚看到您错误地将函数绑定到组件,它是“this.handleSelectClass = this.handleSelectClass.bind(this);”
    • 啊,我错过了 - 非常感谢,已经解决了!
    • @VinishaMittal 更新答案
    猜你喜欢
    • 2020-03-07
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多