简体   繁体   中英

React router 1.0 pass multiple props to children routes

I'm using react-router 1.0 and react-redux on an app, and I'm wondering what strategy is best to pass props to children on larger apps. Here's a basic situation:

Let's say I have a route /admin/users/edit/:id with the following structure on its components:

Routes:

<Router>
  <Route path="admin" component={Admin}>
    <Route path="users" component={Users}>
      <Route path="edit/:id" component={Edit}/>
    </Route>
  </Route>
</Router>

Admin:

class Admin extends React.Component {

  render() {
    return (
      {this.props.children}
    )
  }
}

Users:

class User extends React.Component {

  edit = (id, params) => {
    const { dispatch } this.props;
    dispatch(edit(id, params));
  } 

  other functions (add, remove) ...

  render() {
    return (
      {this.props.children}
    )
  }
}

function mapStateToProps(state) {
  const { users } = state;
  return { users };
}

export default connect(mapStateToProps)(User);

Edit:

class Edit extends React.Component {

  submit () => {
    const { id } = this.props.params;
    const { firstName } = this.refs;
    this.props.edit(id, {firstName: firstName.value});
  }

  render() {
    const { id } = this.props.params;
    const user = this.props.users[id];
    return (
       <form>
         <input ref='firstName' defaultValue={user.firstName}/>
         <button onClick={this.submit}>Submit</button>
       </form>
    )
  }
}

How would I pass the users & edit function props down to the children?

I know about React.cloneElement() (as in https://github.com/rackt/react-router/tree/master/examples/passing-props-to-children ), but if I have multiple routes like /users/add , /users/remove/:id , etc, I would be passing and exposing all the functions (edit, add, remove...) to all children. That solution doesn't seem to work very well when you have more than one children.

I would like to keep my children as dumb as possible, and use this same structure across the application ( /images/add , /images/remove/:id , etc).

Any suggestions?

You have a few options:

First level children:

Use React.cloneElement() , that's something you are already aware of. I wouldn't use it for deeply nested Components though.

To all routes:

Use createElement() :

<Router createElement={createElement} />

// default behavior
function createElement(Component, props) {
  // make sure you pass all the props in!
  return <Component {...props}/>
}

// maybe you're using something like Relay
function createElement(Component, props) {
  // make sure you pass all the props in!
  return <RelayContainer Component={Component} routerProps={props}/>
}

Check more on that in the React Router docs .

Use context:

Note:
Context is an advanced and experimental feature. The API is likely to change in future releases.

See how to use it in the React docs .


There is also the whole thread about it in the react-router#1531 .

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