简体   繁体   中英

React Router: cannot pass props to activeRouteHandler

I'm trying to pass some props down to my handled component however react-router fails to do so.

var Objects = React.createClass({
    getInitialState: function() {
        return {
            selected: "All"
        }
    },
    select: function(opt) {
        this.setState({
            selected: opt
        });
    },
    render: function() {

        return (
            <div>
                <LeftNav select={this.select} />
                <this.props.activeRouteHandler selected={this.state.selected} />
            </div>
        );
    }
});



var routes = (
    <Routes>
        <DefaultRoute name="objects" handler={objecctHandler}/>
    </Routes>
);

The router loads fine as I can see '#/' in the url now. The Left nav renders fine and updates the state as well. however there is not props.selected in the handeded component namely objectHandler. Am I missing something here? Thanks.

I'm using react-router 0.7.0

Try making the DefaultRoute for 'objectHandler' a child of another route that defines 'Objects' as the handler. Such as:

var routes = (
    <Routes>
        <Route handler={Objects}>
            <DefaultRoute name="objects" handler={objectHandler}/>
        </Route>
    </Routes>
);

jsfiddle: http://jsfiddle.net/gq1uym5y/1/

What I'm using right now is something like this.

One top level route that just routes to the App component:

React.renderComponent(
    <Routes>
        <Route handler={App}>
            <Route path="/todos" handler={TodoList} />
        </Route>
    </Routes>
, mountNode);

The App component looks like this. I pass a Container to all subroutes (ie to the TodoList route). This container contains the list of todos (and anything else I need in the app, including methods for adding/persisting new Todos). This helps with keeping state at the top level and decouple subcomponents . Since the App component is used for every route, it never unmounts, so it doesn't loose its state.

var Container = function(app) {
    return {
        getTodos: function() {
            return app.state.todos;
        }
    };
};

var App = React.createClass({
    getInitialState: function() {
        return {
            todos: ['Buy milk', 'Call Mike']
        };
    },

    componentWillMount: function() {
        this.container = Container(this);
    },

    render: function() {
        return <this.props.activeRouteHandler container={this.container} />;
    }
});

Here's what the TodoList looks like. It's actually two components: TodoList and TodoListInner . The TodoListInner remains clean and testable . The TodoList itself is not so easily testable, but since it just wraps around the inner component, this shouldn't be much of a problem.

var TodoListInner = React.createClass({
    render: function() {
        <ul>
            {this.props.todos.map(function(todo) {
                return <li>{todo}</li>;
            })}
        </ul>
    }
})

var TodoList = React.createClass({
    render: function() {
        <TodoListInner todos={this.props.container.getTodos()} />
    }
});

It's a little more complex than jsmiff's solution but does the job with some added benefits.

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