2017-02-13 1 views
0

Ich habe eine Anwendung mit Komponenten in der folgenden Struktur reagieren:Reagieren: nested Komponentenstatus aktualisiert basierend auf onFocus „maximale Anrufstapelgröße überschritten“ error

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

Ich wünsche eine Funktionalität zu übernehmen, wo der Zustand der Die Symbolleiste wird festgelegt, wenn die Eingabe-Schaltflächen in den Abschnitten aktiviert sind (onFocus).

Wie setze ich den Status der Symbolleiste auf die ID des zuletzt ausgewählten Abschnitts? Setze ich den Status in jedem Abschnitt und gehe dann 2 Ebenen nach oben zur Symbolleiste?

Ich habe zumindest eingestellten Zustand in der Wurzelkomponente zu dem fokussierten sectionid versucht, aber jetzt einem anderen Fehlermeldung (maximal Call-Stack erreicht) Ich erhalte, etwa so:

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

Was mache ich falsch, dass ich die maximale Call-Stack-Fehlermeldung bekomme? Gibt es einen einfacheren Weg, um mit dieser Art von Funktionalität umzugehen, oder ist diese Art der reaktiven Vorgehensweise? Sollte ich Redux untersuchen, nur um das effizient zu verwalten?

Jede Hilfe wird sehr geschätzt!

+0

, wenn Sie dies machen als eine Arbeit geschnippelt, wäre es viel besser – havenchyk

+0

'chart.js' =>' this.props.onUpdate (this.state) 'Du machst ein update nach dem update, dann setState der übergeordneten Komponente, was zu einem weiteren check und einem weiteren update führt, vor allem, weil du' 'verwendest this.chartUpdate.bind (this) 'das ist jedes Mal neu.Nur ein Vorschlag :) – havenchyk

+0

Hallo @havenchyk, ich habe meine Frage geändert, um ein funktionierendes Snippet –

Antwort

1

Setzen Sie den Status in jedem Abschnitt, zurück 2 Ebenen nach oben dann bis Symbolleiste? Kein

Wie kann ich den Zustand der Symbolleiste auf die ID des zuletzt ausgewählten Abschnitt?

Sie sollten nur eine Quelle der Wahrheit für Ihre sectionInFocus-Daten haben. Dies bedeutet, dass unabhängig davon, wie viele Eltern Ihre Komponente hat, Sie nur den Status in Ihrer höchsten Root-Komponente festlegen sollten (eine maximale Ebene, auf der Ihre Daten verwendet werden müssen). In Ihrem Fall ist es App Komponente (besser State-Management wie Redux haben, aber das ist jetzt für diese Frage außerhalb des Geltungsbereichs).

So sollten Sie etwas tun:

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