javascript - react : Updating nested component state based on onFocus, "maximum call stack size exceeded"错误

标签 javascript reactjs meteor

我有一个 React 应用程序,其组件具有以下结构:

<App>
    <Toolbar this.state={sectionInFocus: someSectionID }/>
    <Chart>
       <Section> <input value=someSectionID /> <Section />
       <Section> <input value=someSectionID  /> <Section />
       <Section> <input value=someSectionID  /> <Section />
       ...more sections...
    </Chart>
</App>

我希望采用一种功能,当各部分中的输入按钮聚焦(onFocus)时,设置工具栏的状态。

如何将工具栏的状态设置为最后选定部分的 id?我是否要设置每个部分的状态,向上传递 2 个级别,然后传递到工具栏?

我尝试至少将根组件中的状态设置为聚焦的sectionID,但现在我收到另一条错误消息(已达到最大调用堆栈),如下所示:

应用程序.js:

import React, { Component } from 'react';
import Chart from './chart';

export default class App extends Component {

  constructor(props){
    super(props)
    this.state = {
      sectionInFocus: ''
    }
  }

  componentDidUpdate(){
    console.log(this.state); // maximum call stack size exceeded
  }

  chartUpdate(obj){
    const { sectionInFocus } = obj;
    console.log(sectionInFocus);
    this.setState({ sectionInFocus });
  }

  render() {
    return (
    <div>
      <Chart chart={{"chartData":["abc","def","ghi"]}} onUpdate={this.chartUpdate.bind(this)}/>
    </div>
    )
  }

};

Chart.js

import React, { Component } from 'react';
import Section from './section';

export default class Chart extends Component {
  constructor(props) {
    super(props);
    this.state = {
      sectionInFocus: ""
    }
  }

  componentDidUpdate(){
    console.log(this.state.sectionInFocus);
    this.props.onUpdate(this.state);
  }

  sectionUpdate(sectionID) {
    this.setState({sectionInFocus: sectionID});
  }

  renderSections(chartData) {
    return chartData.map((section) => {
      return (
        <Section
          key = {section}
          sectionID = {section}
          onUpdate={this.sectionUpdate.bind(this)}
        />
      )
    })
  }

  render(){
    let chartData = this.props.chart.chartData;
    return (
      <div>
        {this.renderSections(chartData)}
      </div>
    )
  }
}

Section.js

import React, { Component } from 'react';

export default class Section extends Component {
  updateParentState(){
    this.props.onUpdate(this.props.sectionID)
  }
  render(){
    return (
      <div>
        <input
          value={this.props.sectionID}
          onFocus={this.updateParentState.bind(this)}
        />
      </div>
    )
  }
}

我做错了什么,导致我收到最大调用堆栈错误消息?是否有更简单的方法来处理此类功能,或者这是一种 react 方式?我应该考虑 redux 只是为了有效地管理它吗?

非常感谢您提供的任何帮助!

最佳答案

Do I set the state in each section, passing back 2 levels up then to toolbar?

没有

How do I set the state of toolbar to the id of the last selected section?

您的sectionInFocus 数据应该只有一个真实来源。这意味着无论您的组件有多少个父组件,您都应该只在最高根组件中设置状态(需要使用数据的最高级别)。在你的例子中,它是 App 组件(最好有像 Redux 这样的状态管理,但这超出了这个问题现在的范围)。

所以你应该这样做:

应用程序.js:

import React, { Component } from 'react';
import Chart from './chart';

export default class App extends Component {

  constructor(props){
    super(props)
    this.state = {
      sectionInFocus: ''
    }
    this.chartUpdate = this.chartUpdate.bind(this);
  }

  componentDidUpdate(){
    console.log(this.state); // maximum call stack size exceeded
  }

  chartUpdate(obj){
    const { sectionInFocus } = obj;
    console.log(sectionInFocus);
    this.setState({ sectionInFocus });
  }

  render() {
    return (
    <div>
      <Chart chart={{"chartData":["abc","def","ghi"]}} onUpdate={this.chartUpdate}/>
    </div>
    )
  }

};

Chart.js

import React, { Component } from 'react';
import Section from './section';

export default class Chart extends Component {

  renderSections(chartData) {
    return chartData.map((section) => {
      return (
        <Section
          key = {section}
          sectionID = {section}
          onUpdate={this.props.sectionUpdate}
        />
      )
    })
  }

  render(){
    let chartData = this.props.chart.chartData;
    return (
      <div>
        {this.renderSections(chartData)}
      </div>
    )
  }
}

Section.js

import React, { Component } from 'react';

export default class Section extends Component {
  render(){
    return (
      <div>
        <input
          value={this.props.sectionID}
          onFocus={() => this.props.onUpdate(this.props.sectionID)}
        />
      </div>
    )
  }
}

关于javascript - react : Updating nested component state based on onFocus, "maximum call stack size exceeded"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42207313/

相关文章:

javascript - "&="在JS中有什么用?

Javascript - 替换字符串子字符串内的字符

javascript - React native - x 秒后更改屏幕

javascript - 将 redux 存储连接到 nextjs 布局

reactjs - 如何将 Unity WebGL 放入我的 React Native 应用程序中?

html - 如何呈现 Meteor Session 变量的 HTML?

javascript - 如何使表单控件以 "write back"的方式响应?

javascript - 使用 Google Closure Compiler 缩小用 Typescript 编写的 AngularJs 应用程序

javascript - D3.JS 为每个国家添加类

javascript - Meteor AutoForm 中的条件(类别/子类别)选项