0

I have found a bunch of questions that seem like duplicates but I cannot seem to fix this issue I am having. I have a parent component:

class Parent extends Component {
  constructor(props) {
  super(props);

this.state = {
  //some other props
  currentDate: moment()
};

componentDidMount() {
  this.fetchData();
}

fetchData() {
  this.setState({
    //set some state here
  });
  //Some Api call
}

onDateChange(currentDate) {
  this.setState({
    currentDate
  });
}
//doing some stuff to render a table
return (
  <div>
    <ChildComponent
      currentDate={this.state.currentDate}
      onDateChange={(date) => this.onDateChange(date)}
    />
    {currentView}
  </div>
);
}

render() {
 return (
  <div>
    //renders table
  </div>
);

I am able to pass the method onDateChange to the child. And the child looks like:

 class Child extends Component {
   constructor(props) {
   super(props);
   this.state = {
     currentDate: this.props.currentDate,
     focused: false
};

 render() {
   return (
     <div className="form-group">
       <SingleDatePicker
        date={this.state.currentDate}
        onDateChange={(date) => this.props.onDateChange(date)}
        focused={this.state.focused}
        onFocusChange={({ focused }) => this.setState({ focused: focused })}
    />
  </div>
);

For whatever reason I am unable to invoke the onDateChange method. If I console.log(this.props) I can see that the function is being passed as a prop. If I console.log(this.props.onDateChange) it returns:

ƒ onDateChange(currentDate) {
  this.setState({
    currentDate: currentDate
  });
}

I can see the function and the code its supposed to execute. I have tried creating a method that calls this.props.onDateChange and then calling that method but it still does not work. I am confused as to why I am able to get the method to pass as a prop but I cannot invoke it. I realize there are a lot of questions asking how to pass function as a prop (I am able to do this) I just can't get this function to execute. Thanks in advance.

EDIT: I have updated the code to add the suggestions below. I am now getting no errors but It is still not working as expected. I will report back if/when i figure it out.

Progman
  • 16,827
  • 6
  • 33
  • 48

3 Answers3

1

You forgot to invoke the function inside the arrow function:

        onDateChange={(date) => this.props.onDateChange(date)}
Chris
  • 6,331
  • 1
  • 21
  • 25
  • Hi @Christiaan I edited my question to include your advice. Its still not working as expected but i am making progress. So thank you. –  Dec 13 '19 at 16:59
  • Have you figured it out? – Chris Dec 17 '19 at 12:56
0

To pass the method to the child, remove the .bind(this):

class Parent extends Component {
  constructor(props) {
  super(props);

this.state = {
  //some other props
  currentDate: moment()
};

componentDidMount() {
  this.fetchData();
}

fetchData() {
  this.setState({
    //set some state here
  });
  //Some Api call
}

onDateChange(currentDate) {
  this.setState({
    currentDate
  });
}
//doing some stuff to render a table
return (
  <div>
    <ChildComponent
      currentDate={this.state.currentDate}
      // Removed .bind(this)
      // added missing parameter
      onDateChange={(date) => this.onDateChange(date)}
    />
    {currentView}
  </div>
);
}

render() {
 return (
  <div>
    //renders table
  </div>
);
Typeset
  • 26
  • 6
  • Hi, thanks for the response. I removed the bind and am getting a new error that setState in method onDateChange is not a function. But at least that gives me more to work with. Thank you! –  Dec 13 '19 at 16:37
  • I was able to get rid of the setState is not a function error by binding onDateChange to this in the constructor. Its still not working as expected but I am making progress. –  Dec 13 '19 at 16:45
  • 1
    Christiaan's answer shows how to pass the missing date parameter to your parent component's function - I've added the parameter to my answer. – Typeset Dec 13 '19 at 16:47
  • Hi, @Typeset, I used yours and Christiaan's answers and updated my question to reflect. Its not working as expected yet but I am making progress. So thank you guys. –  Dec 13 '19 at 16:58
0

Could you share the complete file, including the import classes and the export as well?

From this part of the code shared, some issues that I can see:

  • The constructors of both classes are missing a closing bracket;
  • The return in Parent (//doing some stuff to render a table) is misplaced. Did you want to put that inside the render method?

Maybe something like this?

class Parent extends Component {
  constructor(props) {
    super(props);

    this.state = {
      //some other props
      currentDate: moment()
    };
  }

  componentDidMount() {
    this.fetchData();
  }

  fetchData() {
    this.setState({
      //set some state here
    });
    //Some Api call
  }

  onDateChange(currentDate) {
    this.setState({
      currentDate
    });
  }

  render() {
    //doing some stuff to render a table
    return (
      <>
        <div>
          <ChildComponent
            currentDate={this.state.currentDate}
            onDateChange={this.onDateChange.bind(this)}
          />
          {currentView}
        </div>
        <div>
          {/* renders table */}
        </div>
      </>
    );
  }
}

There are still missing pieces in here like this currentView, so, if you could give more context, it would be great.

I hope it helps.

  • @Typeset, by `currentView`, did you mean `currentDate`? – Geraldo B. Landre Dec 13 '19 at 17:03
  • Hi thanks for your response, most of the other code is just logic to render the table. The actual functionality of this is sending the date to a DB and changing a SQL query based on that date and then rendering a table of those records. In short, if there is a record for today, the table renders its just the changing date functionality that isn't working. –  Dec 13 '19 at 17:07