1

I've got a parent component with react-router, setup like this :

constructor(props){
    super(props);

    this.state = {
        diner: false
    };

    this.updateFromInvite = this.updateFromInvite.bind(this);
}

updateFromInvite(Souper) {
    this.setState({diner: Souper});
}

I can't figure out how to setup the route to have both URL parameters and be able to pass a function to update the parent's state from the children component...

<Route path="/Invitation/:NomParam1?/:NomParam2?" 
       component = {() => (<Invitation updateApp = {this.updateFromInvite} />)} />

I think it's the closest I got...

From children's component :

class Invite extends Component {
    constructor(props){
        super(props);
        this.state = {
            diner: this.props.match.params.NomParam1 ,
            JSONInfo: this.props.match.params.NomParam2
        };
    }

    componentDidMount() {
        const { diner } = this.state;
        const { JSONInfo } = this.state;
        const { updateApp } = this.props;
        updateApp(diner);
    }

  render() {
    return (
      <div className="Invite">
        <div className="col-centered">
            <VidPlay/>
        </div>
      </div>
    );
  }
}

export default Invite;
R3uK
  • 14,417
  • 7
  • 43
  • 77
  • You seem to mix up `render` with `component`. The render method has a parameter that contains the `match` that made the route active. – Icepickle Nov 07 '17 at 21:17

2 Answers2

1

The component property of the route takes a component Class, not an instance of the component. I believe you are looking to use the render property, which takes a rendered component. Your visual component shouldn't be concerned with the routing details, so you can pass that in in the Route configuration like so:

<Route path="/Invitation/:NomParam1?/:NomParam2?" 
  render={({match}) => (
    <Invitation
      updateApp={this.updateFromInvite}
      diner={match.params.NomParam1}
      JSONInfo={match.params.NomParam2}
    />
  )}
/>

Then, in the component, don't utilize state, as that's not really what it is for:

class Invite extends Component {
    componentDidMount() {
        const { diner, JSONInfo, updateApp } = this.props;

        // Not exactly sure what is going on here... how you
        // will use JSONInfo, etc
        updateApp(diner);
    }

  render() {
    return (
      <div className="Invite">
        <div className="col-centered">
            <VidPlay/>
        </div>
      </div>
    );
  }
}

Also, I'm not exactly sure what the parent component is doing, and why it is passing both the route params and the function down to the child, only to have the child call it back... but that is probably out of the scope of the question.

Enjoy!

Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
  • I'm still getting `Cannot read property 'params' of undefined` on `diner: this.props.match.params.NomParam1` . Even, when I'm trying with parameters... If I take a closer look at `this.props` inside children, I do have `updateApp`, but I no longer have `match`, `location`, `history`, ... – R3uK Nov 08 '17 at 07:44
  • Oh, I see... yeah, that's because I didn't see that you are reading the match parameters in your component. Your component shouldn't be concerned with routing... it should take two parameters (not state). From what I understand of your example, it would be `diner` and `JSONInfo`, though I don't know what `JSONInfo` is... it probably needs a different name. I'll update the example. – Brian Genisio Nov 08 '17 at 21:51
0

If finally got it (thanks to that answer and the official documentation):

I needed to add props as parameter of my render and
use it with {...props} inside the children element!

<Route path="/Invitation/:NomParam1?/:NomParam2?" 
       render={ (props) => 
                (<Invitation updateApp = {this.updateFromInvite} {...props} />) 
              }
/>

With that, I have access to BOTH :

  • my custom props
  • generic props (match, location and history)
R3uK
  • 14,417
  • 7
  • 43
  • 77