2016-07-01 5 views
2

Haftungsausschluss: Ich habe mir Reactjs: how to modify child state or props from parent? angesehen und glaube nicht, dass die Antwort meine Frage passt.ReactJS: Muting Kind Staat von Eltern über Requisiten

So habe ich eine wiederverwendbare, statusbehaftete Konversationskomponente, die verschiedene DOM basierend auf seinem Status rendert. Ich muss auch steuern können, welches DOM vom übergeordneten Element gerendert wird.

TL; DR - Wie sollte ich einen Kind-Komponenten-Status vom Elternteil mutieren, wenn überhaupt, welche anderen Optionen gibt es?

Das Kind:

export default class Conversation extends Component { 
 
    constructor(props) { 
 
    super(props); 
 
    
 
    this.state = { 
 
     newConversation: props.showNewConversation 
 
    }; 
 
    } 
 
    
 
    render() { 
 
    if (!this.state.newConversation) { 
 
    return (
 
     <div>Current Conversation</div> 
 
    ); 
 
    } return (
 
     <div>New Conversation</div> 
 
    ); 
 
    } 
 
}

Jetzt muss ich diese Komponente an verschiedenen Orten machen, aber ich brauche die entsprechenden DOM in Abhängigkeit von der Mutter zu machen, dh von der navbar können Sie Erstellen Sie eine neue Konversation, und von der Benutzerseite können Sie direkt zu Ihrer Konversation mit ihnen gehen, so dass ich steuern kann, wenn ich das Kind über seine Requisite anrufe.

Kind aufrufen und Zustand über prop Einstellung:

<Conversation 
 
    showNewConversation={this.state.isConversationShown === true} 
 
/>

Diese arbeitet derzeit, aber ich habe gesagt, das ist eine sehr schlechte Praxis in Reaktion, ist meine Frage, warum eigentlich Dies wird als schlechte Praxis angesehen, und wie eine gute Praxislösung aussehen würde.

+0

Warum dies für Daten eine sehr schlechte Praxis ist vom Eigentümer fließt zu owned Komponente durch 'Requisiten'? –

Antwort

4

In React besteht die allgemeine Best Practice darin, möglichst viele Komponenten möglichst state-less zu machen. Normalerweise ist der Status nicht erforderlich, wenn Sie keine asynchronen Daten laden oder Benutzereingaben akzeptieren.

In diesem Beispiel geschieht das Hauptproblem wie folgt: Wenn die Eltern

<Conversation newConversation={true} /> 

macht Und später rerenders es

<Conversation newConversation={false} /> 

Dann wird das Kind nicht machen, wie erwartet, wie reagieren " Aktualisieren Sie die untergeordnete Konversation (erneutes Rendern), rufen Sie den Konstruktor jedoch nicht erneut auf. Da Sie im Konstruktor nur die Requisiten in den Zustand übernommen haben, ändert sich das Kind nie.

Vielmehr sollten die meisten Komponenten nur in Abhängigkeit von ihren Eigenschaften rendern. Ihr Kind kann an folgenden angepasst werden:

export default class Conversation extends Component { 
    constructor(props) { 
    super(props); 
    } 

    render() { 
    if (!this.props.newConversation) { 
    return (
     <div>Current Conversation</div> 
    ); 
    } return (
     <div>New Conversation</div> 
    ); 
    } 
} 

Hier ein Update von den Eltern wird das Kind erlaubt, wieder richtig zu machen, weil Sie direkt die Requisiten in der render() Funktion des Kindes verweisen.

Wenn Sie mehr Daten über die Wiedergabe der Konversation hatten, sollten Sie alle Daten als Prop-Datei übergeben. d. h.

Dann kann die Conversation-Komponente direkt auf die Requisiten in der render() -Methode zugreifen.

Wenn Sie absolut müssen den Zustand ändern, dann sollte es von den Eltern in Requisiten in Form einer Veränderung:

export default class Conversation extends Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     newConversation: props.showNewConversation 
    }; 
    } 

    // Response to change 
    componentWillReceiveProps(nextProps){ 
     this.setState({newConversation: this.props.showNewConversation}); 

    } 

    render() { 
    if (!this.state.newConversation) { 
    return (
     <div>Current Conversation</div> 
    ); 
    } return (
     <div>New Conversation</div> 
    ); 
    } 
} 
+0

Super Antwort! es aus dem Zustand zu nehmen und nur als Requisite auf die Konversation einzutauschen, hat sich gelohnt und ist viel sauberer. Danke vielmals! –