2017-02-13 10 views
0

У меня реагируют приложение с компонентами в следующей структуре:React: Обновление вложенного состояния компонента на основе OnFocus, «Максимальный размер стека вызовов превысил» ошибки

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

Как настроить состояние панели инструментов на идентификатор последнего выбранного раздела? Я устанавливаю состояние в каждом разделе, возвращая 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> 
    ) 
    } 

}; 

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

Что я делаю неправильно, что получаю сообщение об ошибке максимального количества вызовов? Есть ли более простой способ справиться с такой функциональностью или это способ реагирования? Должен ли я смотреть на сокращение только для того, чтобы эффективно управлять этим?

Любая предоставленная помощь приветствуется!

+0

, если вы сделаете это как рабочий отрезанный, было бы намного лучше – havenchyk

+0

'chart.js' =>' this.props.onUpdate (this.state) 'вы делаете обновление после обновления, затем setState родительского компонента, который приводит к другой проверке и другому обновлению, особенно потому, что вы используете' this.chartUpdate.bind (this) ', который является новым каждый раз.Просто предложение :) – havenchyk

+0

привет @havenchyk, я изменил свой вопрос, чтобы включить рабочий снимок –

ответ

1

Я устанавливаю состояние в каждом разделе, проходя обратно 2 уровня вверх до панели инструментов? не

Нет

Как установить состояние панели инструментов ид последнего выбранного раздела?

У вас должен быть только один источник истины для ваших данных разделаInFocus. Это означает, что независимо от того, сколько у вас родителей на вашем компоненте, вы должны установить только состояние в своем самом высоком корневом компоненте (максимальный уровень, в котором должны использоваться ваши данные). В вашем случае это компонент 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: '' 
    } 
    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> 
    ) 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^