简体   繁体   中英

ReactJS propagate data between Components

I am working on an SPA with ReactJS. I have a root component App and then several child components. In the the App component I am trying to store some application level state such as logged in user id, and other data. However I am not seeing my state be propagated down the child components.

App

import { Router, Route, Link, IndexRoute, browserHistory, hashHistory } from 'react-router';
import ParameterContainer from './components/parameter/parameter-container';
import NavMenu from './components/navigation/nav-menu';
import {Alert} from 'react-bootstrap';
import SelectFilter from './components/sample/sample-container';

// Main component and root component
export default class App extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            userId: null,
            roles: null,
            parameterTypes: {
                'STRING': 'STRING',
                'BOOLEAN': 'BOOLEAN',
                'INTEGER': 'INTEGER',
                'DECIMAL': 'DECIMAL'
            }
        };
    }

    render() {
        return (
            <div>
                <NavMenu />
                <div className="container">
                    {this.props.children}
                </div>
            </div>
        )
    }
}

// page for 404
class NoMatch extends React.Component {
    render() {
        return (
            <div className="container">
                <Alert bsStyle="danger">
                    <h1>404: Not Found</h1>
                    <h3>The requested resource does not exist!</h3>
                </Alert>
                <img src="images/404.png" style={{display: 'block', margin: '0 auto', width: 300, height: '*'}} />
            </div>
        )
    }
}

// render the application
ReactDOM.render((
    <Router history={hashHistory}>
        <Route path="/" component={App}>
            <Route path="parameter" component={ParameterContainer} />
            <Route path="sample" component={SelectFilter} />
            <Route path="*" component={NoMatch}/>
        </Route>
    </Router>
), document.getElementById('react'))

Child Component

import React from 'react';

export default class ParameterContainer extends React.Component {

    constructor(props) {
        super(props);
        this.state = { parameters: [] };
        this.client = rest.wrap(mime);
        this.fetchFromApi = this.fetchFromApi.bind(this);

        console.log('Props:' + props);
    }

    render() {
        ....
    }

The this.props does not contain what I expected. I need to pass data down to children components.

State is not propagated to child components - you have to set props on child components to pass down data. You can use React.cloneElement to add properties to children:

let childrenWithProps = React.cloneElement({this.props.children, {
        userid: this.state.userId,
        ...
    });

The best way would be to use Redux to manage application data and store application level state in Redux store. If you don't use Redux you can also consider using react Context . According to docs you can use Context if:

you want to pass data through the component tree without having to pass the props down manually at every level

To pass the state or props to the child component you can explicit them on your Route node

   <Route path="parameter" component={ParameterContainer} parentState={this.state} />

You can, then, access them in the child component as props

 constructor(props) {
   super(props)
   console.log('parentState:' + props.parentState);
 }

Here are better and more detailed answers: react-router - pass props to handler component

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM