Javascript React:基于onFocus“更新嵌套组件状态”;超过最大调用堆栈大小;错误

Javascript React:基于onFocus“更新嵌套组件状态”;超过最大调用堆栈大小;错误,javascript,reactjs,meteor,Javascript,Reactjs,Meteor,我有一个react应用程序,其组件结构如下: <App> <Toolbar this.state={sectionInFocus: someSectionID }/> <Chart> <Section> <input value=someSectionID /> <Section /> <Section> <input value=someSectionID /

我有一个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,但现在我收到另一条错误消息(已达到最大调用堆栈),如下所示:

App.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>
    )
  }

};
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>
    )
  }

};
import React,{Component}来自'React';
从“./Chart”导入图表;
导出默认类应用程序扩展组件{
建造师(道具){
超级(道具)
此.state={
sectionInFocus:'
}
}
componentDidUpdate(){
console.log(this.state);//超出了最大调用堆栈大小
}
图表更新(obj){
const{sectionInFocus}=obj;
console.log(sectionInFocus);
this.setState({sectionInFocus});
}
render(){
返回(
)
}
};
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>
    )
  }
}
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>
    )
  }
}
import React,{Component}来自'React';
从“./节”导入节;
导出默认类图表扩展组件{
建造师(道具){
超级(道具);
此.state={
sectionInFocus:“
}
}
componentDidUpdate(){
console.log(this.state.sectionInFocus);
this.props.onUpdate(this.state);
}
sectionUpdate(sectionID){
this.setState({sectionInFocus:sectionID});
}
渲染片段(图表数据){
返回chartData.map((节)=>{
返回(
)
})
}
render(){
让chartData=this.props.chart.chartData;
返回(
{this.renderSections(chartData)}
)
}
}
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>
    )
  }
}
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>
    )
  }
}
import React,{Component}来自'React';
导出默认类节扩展组件{
updateParentState(){
this.props.onUpdate(this.props.sectionID)
}
render(){
返回(
)
}
}
我得到最大调用堆栈错误消息的错误是什么?是否有一种更简单的方法来处理这类功能,或者是这种反应方式?我是否应该研究redux以有效地管理它

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

我是否在每个部分设置状态,然后将2个级别传递回 工具栏

没有

如何将工具栏的状态设置为最后一个选定工具栏的id 部门

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

所以你应该这样做:

App.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>
    )
  }

};
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>
    )
  }

};
import React,{Component}来自'React';
从“./Chart”导入图表;
导出默认类应用程序扩展组件{
建造师(道具){
超级(道具)
此.state={
sectionInFocus:'
}
this.chartUpdate=this.chartUpdate.bind(this);
}
componentDidUpdate(){
console.log(this.state);//超出了最大调用堆栈大小
}
图表更新(obj){
const{sectionInFocus}=obj;
console.log(sectionInFocus);
this.setState({sectionInFocus});
}
render(){
返回(
)
}
};
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>
    )
  }
}
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>
    )
  }
}
import React,{Component}来自'React';
从“./节”导入节;
导出默认类图表扩展组件{
渲染片段(图表数据){
返回chartData.map((节)=>{
返回(
)
})
}
render(){
让chartData=this.props.chart.chartData;
返回(
{this.renderSections(chartData)}
)
}
}
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>
    )
  }
}
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>
    )
  }
}
import React,{Component}来自'React';
导出默认类节扩展组件{
render(){
返回(
this.props.onUpdate(this.props.sectionID)}
/>
)
}
}

如果您将其作为一个工作截图,它会更好
chart.js
=>
this.props.onUpdate(this.state)
您在更新之后进行更新,然后设置父组件的状态,这将导致另一次检查和更新,特别是因为您使用的是
this.chartUpdate.bind(this)
每次都是新的。只是一个建议:)嗨@havenchyk,我修改了我的问题,加入了一个工作表snippet@havenchyk关于更新后更新的问题,我知道你来自哪里。这似乎是正确的方向,尽管我不确定什么是合适的解决方法,我想创建一个从SO(或JSFIDLE)直接工作的代码段,但无论如何,谢谢