当前位置: 首页 > 知识库问答 >
问题:

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

饶谦
2023-03-14

我有一个反应应用程序的组件在以下结构:

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

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

我得到最大调用堆栈错误消息的错误是什么?是否有一种更简单的方法来处理这类功能,或者是这种反应方式?我是否应该研究redux以有效地管理它?

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

共有1个答案

燕智
2023-03-14

我是否在每个部分中设置状态,然后向上传递2个级别到工具栏?

如何将工具栏的状态设置为最后选定部分的id?

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

所以你应该这样做:

pp.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>
    )
  }
}
 类似资料:
  • React.js用props给后代组件发值错了? 我编写了前面的演示来测试使用向后代组件发送信息。但它导致了错误: 未捕获的范围错误:对象超过了最大调用堆栈大小。克隆元素 但是我在演示运行良好后才写,所以你能告诉我是什么原因导致错误吗?

  • 对于我的节点应用程序,我有一个运行在Debian上的服务器(app.js),它使用socket.io向我的客户机(index.html)提供html和websocket数据。我正在尝试制作一个回合制的HTML5多人游戏。 在使用socket.emit()/io.emit()和socket.on()成功执行了多次数据传输后,我的服务器在socket.emit()调用上崩溃,出现错误 “events.

  • //{this.props.params.item}来自反应路由器(路径('/detail/item/id')) 为什么我的调度是无限循环,直到出错(超过最大调用堆栈大小)

  • 问题内容: 我正在使用Direct Web Remoting(DWR)JavaScript库文件,并且仅在Safari(台式机和iPad)中出现错误 它说 超出最大呼叫堆栈大小。 该错误的确切含义是什么,它会完全停止处理吗? 也适用于浏览器的所有修复程序(实际上在上, JS:执行超出超时 我假设是相同的调用堆栈问题) 问题答案: 这意味着在代码的某处,你正在调用一个函数,该函数又调用另一个函数,依

  • 问题内容: 我无法终生弄清楚为什么我会出错: 超过最大呼叫堆栈大小 运行此代码时。如果我注释掉: 错误消失了。我什至已注释掉其他电话,以尝试缩小问题的出处。 代码(删除了额外的功能): 问题答案: 由于此循环: 您正在从render调用getTabs方法,并在其中进行操作,将触发重新渲染,再次是getTabs ..... 无限循环 。 从方法中删除,它将起作用。 另一个问题在这里: 我们需要为on

  • 问题内容: 我正在做反应,基本上我想用工具提示制作一个按钮,现在我正在制作工具提示。我正在更改css display属性,以使其在鼠标进入和离开时不可见。但是有一个错误,我不知道该怎么办… 这是我的代码: 在控制台中,我收到此错误: 我找不到问题所在。我知道这可能与调用一个函数有关,后者又调用另一个函数。但是我在代码中看不到这样的东西,而且不确定是否全部。感谢帮助 :) 问题答案: 每当您看到从函