0

Trying to set state in parent component (named parent.js) with a date selected in a child component named 'Book' in file 'daySelect.js' for taking down reservation details. Getting an error, though, saying the function (onUpdate) I'm calling from child to update state in parent is "not a function":

Parent Coding (parent.js):

class Parent extends Component {
  // Setting the component's initial state
  constructor(props) {
    super(props);
  this.state = {
    date: "",
  };
}

onUpdate = (dateChosen) => {
  this.setState({
    date: dateChosen
    })
   console.log(this.state.date);
    };

render() {
return (
  <div>
        <Route exact path="/" component={Home} />
        <Route exact path="/book" component={Book} onClick={this.onUpdate}/>
        <Route exact path="/time" component={Time} />
        <Route exact path="/form" component={Form} />
  </div>
);

} }

Child Component:

class Book extends Component {
// Setting the component's initial state
 constructor(props) {
   super(props);
 }

  onClick = (date) => {
   var dateChosen = date[0];
   // console.log(dateChosen);
   this.props.onUpdate(date);
   this.setState({date: dateChosen});
  };


 render() {
  return (
    <div>
     <ReactWeeklyDayPicker mobilView={window.innerWidth < 100} format={'YYYY-MM-DD'} selectDay={this.onClick.bind(this)} />
    </div>
);
}

export default Book;
Eric K.
  • 121
  • 3
  • 17
  • 1
    `onUpdate = (dateChosen) => {` probably should be `onUpdate(dateChosen) {`. – Tyler Oct 26 '18 at 12:52
  • Can I make a suggestion,.. React is great, but using state can get messy. A common approach using React is to use the `Single Source of Truth` ideology. Redux is popular, but I found it too verbose, and rolled my own state management using proxy's. – Keith Oct 26 '18 at 12:57

2 Answers2

4

You passed a function called onClick to your Book component, so you have to write this.props.onClick and not this.props.onUpdate

Try to either change your onClick to onUpdate or to call this.props.onClick(data) instead of this.props.onUpdate(data)

UPDATE : You can now pass childrens to Route

<Route exact path="/book"><Book {...props} onClick={this.onUpdate}/></Route>

UPDATE : Now you have to change your nested children to an element={} in React Router v6

<Route path=":id" element={<Book />} />
Victor Jozwicki
  • 700
  • 2
  • 10
  • 24
  • Thanks, Victor, but still getting the following error message even after change of this.props.onUpdate(data) to this.props.onClick(data): TypeError: _this.props.onClick is not a function Feel like parent & child are not effectively communicating between one another.. – Eric K. Oct 26 '18 at 13:09
  • I wasn't able to check it thoroughly but I knew something was fishy about passing the function to a Router as I've never done that – Victor Jozwicki Oct 26 '18 at 16:06
3

Two things that you haven't done correctly.

First: You cannot pass the props to the Route component directly, you need to use render prop to do that

Check Passing custom props to router component in react-router v4 for more details

Second: you can access the props in child component with the name that you have passed it by. In your case it will be this.props.onClick instead of this.props.onUpdate

class Parent extends Component {
  // Setting the component's initial state
  constructor(props) {
    super(props);
  this.state = {
    date: "",
  };
}

onUpdate = (dateChosen) => {
  this.setState({
    date: dateChosen
    })
   console.log(this.state.date);
    };

    render() {

        return (
          <div>
                <Route exact path="/" component={Home} />
                <Route exact path="/book" render={(props) => <Book {...props} onClick={this.onUpdate}>} />
                <Route exact path="/time" component={Time} />
                <Route exact path="/form" component={Form} />
          </div>
        );

    }

}
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400