2015-07-13 11 views
5

Ich bin neu zu reagieren und zu versuchen, eine einfache ToDo-App basierend auf dem Reagieren-Starter-Kit zu bauen. Ich verwende ES6-Klassen und konnte keine Möglichkeit finden, den übergeordneten Status von einer untergeordneten Komponente zu aktualisieren. HierReact ES6 Eltern Kind Komponenten Status Problem

ist der Code:

import React, { PropTypes, Component } from 'react'; 
import withStyles from '../../decorators/withStyles'; 
import styles from './ToDoPage.less'; 


@withStyles(styles) 
class ToDoPage extends Component { 

    static contextTypes = { 
    onSetTitle: PropTypes.func.isRequired 
    }; 

    constructor() { 
    super(); 
    this.state = { 
     items: ['Item1', 'Item2'], 
     value: '' 
    }; 
    } 

    updateValue(newValue) { 
    //this.state is null here 
    this.setState({ 
     value: newValue 
    }); 
    } 

    clickHandler() { 
    console.log('AddToDo state:', this.state) 
    if (this.state.value && this.state.items) { //this.state is null here 
     this.setState({ 
     items: this.state.items.push(this.state.value) 
     }); 
    } 
    } 

    render() { 
    let title = 'To Do List'; 
    this.context.onSetTitle(title); 
    return (
     <div className="ToDoPage"> 
     <div className="ToDoPage-container"> 
     <h1>{title}</h1> 
      <AddToDoTextBox handleUpdate={this.updateValue}/> 
      <AddToDoButton handleClick={this.clickHandler}/> 
      <div className = "todo-items"> 
      <br/> 
      <div>({this.state.items.length}) items found.</div> 
      <ToDoList items = {this.state.items}/> 
      </div> 
     </div> 
     </div> 
    ); 
    }; 
} 

class ToDoList extends Component { 
    static propTypes = { 
    items: PropTypes.array.isRequired 
    }; 

    render() { 
    console.log(this.props.items); 
    return (
      <ul> 
      {this.props.items.map(function(item) { 
      return <li key={item}>{item}</li> 
      }) } 
      </ul>); 
    }; 
}; 

class AddToDoButton extends Component { 
    static propTypes: { 
    clickHandler: React.PropTypes.func 
    } 

    constructor() { 
    super(); 
    } 

    render() { 
    return (<button 
      className="btn btn-primary" 
      onClick={this.props.handleClick.bind(this)}>Add ToDo</button>); 
    }; 
} 

class AddToDoTextBox extends Component { 
    static propTypes: { 
    handleUpdate: React.PropTypes.func 
    } 

    constructor() { 
    super(); 
    this.state = { 
     value: '' 
    }; 
    this.handleChange = this.handleChange.bind(this); 
    } 

    handleChange(e) { 
    this.setState({value: e.target.value}); 
    this.props.handleUpdate.call(this, e.target.value); 
    } 

    render() { 
    return <input type="text" placeholder="Enter todo item here" size="50" onChange={this.handleChange}/> 
    }; 
} 
export default ToDoPage; 

Ich möchte ToDoPage des Staates von Update() und clickhandler() Funktionen zuzugreifen aber this.state ist null, wie ich auf die untergeordneten Komponenten Bindung sie genannt werden (zB AddToDoButton und AddToDoTextBox). Wie kann ich den Status von ToDoPage über clickHandler() oder updateValue() abrufen/aktualisieren?

+0

möglich Duplikat [Reagieren ref und setState nicht mit ES6 Arbeit] (http : //stackoverflow.com/questions/29577977/react-ref-and-setstate-not-working-with-es6) – loganfsmyth

Antwort

5

Wenn Sie Änderung, die Sie vom Kind zum Elternteil tun wollen, müssen eine Funktion an das Kind als Prop übergeben. So etwas wie (Beispiel mit einiger ES7-Syntax):

Geordnete Komponente

import React, { Component } from 'react' 

export default class Parent extends Component { 
    constructor() { 
    super(); 

    this.handleChange = this.handleChange.bind(this); 
    this.state = { 
     number: 1 
    }; 
    } 

    handleChange(num) { 
    this.setState({ 
     number: num 
    }); 
    } 

    render() { 
    return (
     <Child changeNumber={this.handleChange} /> 
    ); 
    } 
} 

Kinderkomponente

import React, { PropTypes, Component } from 'react' 

export default class Child extends Component { 
    static propTypes = { 
    changeNumber: PropTypes.func 
    } 

    constructor() { 
    super(); 

    this.handleClick = this.handleClick.bind(this); 
    } 

    handleClick(e) { 
    e.preventDefault(); 
    this.props.changeNumber(e.target.value); 
    } 

    render() { 
    return (
     <button onClick={this.handleClick}> 3 </button> 
    ); 
    } 
}