Respond to the state of ES6 parent child components

I am new to reacting and trying to create a simple ToDo application based on a set of reactive starters. I am using ES6 classes and cannot find a way to update the parent state from the child component.

Here is the 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; 

I want to access the ToDoPage state from the updateValue () and clickHandler () functions, but this.state is null since I bind to the child components from which they are called (e.g. AddToDoButton and AddToDoTextBox). How can I access / update ToDoPage state from clickHandler () or updateValue ()?

+5
source share
2 answers

You need to use .bind(this) in your handleUpdate and handleClick in ToDoPage.render() :

  <AddToDoTextBox handleUpdate={this.updateValue.bind(this)}/> <AddToDoButton handleClick={this.clickHandler.bind(this)}/> 

or use arrow functions

See https://facebook.imtqy.com/react/docs/reusable-components.html#no-autobinding

+4
source

If you want to make changes with Child to Parent, you need to pass the Child function as a support. Something like (example with some ES7 syntax):

Parent component

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

Child component

 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> ); } } 
+5
source

All Articles