23. Reactjs - passing data from child to parent

home

Contents

1. Description

// App.js ----------------------------------------------------- render() { return ( <div className="app"> <Menu /> {(this.props.location.pathname === "/") ? <Home />: (this.props.location.pathname === "/up") ? <Up onNewData={this.processUpData}/> : (this.props.location.pathname === "/add-city") ? <AddCityForm onNewCity={this.addCity}/> : (this.props.location.pathname === "/down") ? <Down p1={this.state.greet} p2={this.state.name}/> : <Whoops404/> } </div> ) }

2. Related structure, index.js and Menu.js

// --- related folder and file structure ------ | src | components App.js Menu.js Home.js Down.js Up.js AddCityForm.js Whoops404.js | stylesheets ... index.js // --- index.js ----------------------------------- import React from 'react' import { render } from 'react-dom' import './stylesheets/ui.scss' import { App } from './components/App' import { Router, Route, hashHistory } from 'react-router' window.React = React render( <Router history={hashHistory}> <Route path="/" component={App}/> <Route path="/home" component={App}/> <Route path="/down" component={App} /> <Route path="/up" component={App} /> <Route path="add-city" component={App} /> </Router>, document.getElementById('react-container') ) // --- Menu.js ------------------------------------- import { Link } from 'react-router' import HomeIcon from 'react-icons/lib/fa/home' export const Menu = () => <nav className="menu"> <Link to="/" activeClassName="selected"> <HomeIcon /> </Link> <Link to="/down" activeClassName="selected"> data down </Link> <Link to="/up" activeClassName="selected"> data up </Link> <Link to="/add-city" activeClassName="selected"> add city </Link> </nav>

3. passing data from parent to child

// Down.js the receiver --------------------- export const Down = ({p1, p2}) => ( <div> <div> <span>{p1}</span> </div> <div> <span>{p2}</span> </div> </div> ) // App.js the sender --------------------- export class App extends Component { constructor(props) { super(props) this.state = { greet: "Hello", name: "Peter" } } ..... <Down p1={this.state.greet} p2={this.state.name}/>

4. passing data from child to parent

4.1 App.js     render method <Up onNewData={this.processUpdata} />
        4.2   App.js       ProcessUpData(data)     the event handler
                 processUpData(data){
                     console.log('enter processData')
                     console.log('data = ' + JSON.stringify(data))
                     console.log('msg = ' + data["msg"])
                     console.log('no = " + data["no"])
                 }
            
        4.3   Up.js 
            export const Up = ({data, onNewData}) => {
            const passData = (e) => {
              e.preventDefault()
              
              onNewData({                               // in child, it is a function
                  msg: "message from child to parent",  // invoke the function automatically
                  no: 1                                 // the react will create a event accordingly
              })
              
            }
            
return ( <div> <div> <h2>Up component</h2> <p>xxx</p> </div> <button onClick={passData}>Click to pass data from child to parent</button> </div> )

5. passing data from child(form) to parent

// App.js ----------------------------------------------------------- <AddCityForm onNewCity={this.addCity}/> // create a child(form) addCity(newCity) { // the event handler for event onNewCity console.log('enter addCity') console.log('newDay = ' + JSON.stringify(newCity)) } // within the constructor for App, it is needed for addCity is an event handler. this.addCity = this.addCity.bind(this) // AddCityForm.js ----------------------------------------- import { PropTypes } from 'react' export const AddCityForm = ({ city, state,onNewCity }) => { let _city, _state const submit = (e) => { e.preventDefault() onNewCity({ city: _city.value, state: _state.value }) _city.value = '' _state.value = '' } return ( <form onSubmit={submit} className="add-day-form"> <label htmlFor="city">City</label> <input id="city" type="text" required defaultValue={city} ref={input => _city = input}/> <label htmlFor="state">State</label> <input id="state" type="text" required defaultValue={state} ref={input => _state = input}/> <button>Add Day</button> </form> ) } AddCityForm.defaultProps = { city: "Boston", state: "MA" } AddCityForm.propTypes = { city: PropTypes.string.isRequired,state: PropTypes.string.isRequired }