2

I have a function in my parent component which is sent to the child components as a prop.In one of my child component,I want the same function(which was sent as a prop from the parent component) to be run twice.The first will be run with some arguments and return the value from that particular child component.The second will be to pass the same function(which came from the parent component,not the one executed in this component) to a separate component as a props again.So my function is:

//Function defined in the parent component and sent as props to the child components
  handleShelfChange = (bookOnChange, newSehlf) => {
     !this.isTheBookNew(bookOnChange) && this.setState(state => {
     let newBooks = state.books.map(book =>
       { if (bookOnChange.id === book.id)
         { book.shelf = newSehlf; }
         return book;
       });
         return {
            books: newBooks
           };
          }
        );
        BooksAPI.update(bookOnChange, newSehlf);
        };

I am sending this function to one of the child component as shown below:

<BookSearch
  books={this.state.books}
  handleShelfChange={this.handleShelfChange}/>

Now, in my BookSearch Component,I need to perform 2 actions:

1) Use handleShelfChange() method and return values from BookSearch Component.

2) Pass handleShelfChange() method to another component as props which will use the same method again and return some values.

So,I am facing some issues in the first point, I am using the function as a callback to this.setState as

  this.setState({ books : book_search }, this.check()); // callback function to this.setState

and the callback function is as shown below:

check() {
    let parent_books = this.props.books;
    let shelf;
    console.log(this.state.books)
    const book_result = this.state.books.map((book) => {
      const parent = parent_books.find(parent => parent.title === book.title );
       if(parent) {
        console.log(parent);
        book.shelf = parent.shelf;
        let shelfChange = this.props.handleShelfChange(book,book.shelf) //Call to the 
                                                  //function sent as props from the parent component
            shelf = shelfChange
              }

            console.log(shelf)   // undefined

            return [book,shelf];
        })
        //console.log(book_result);
        this.setState({books: book_result})
        console.log(this.state.books)
      }

So,I need to run the handleShelfChange() function here for all the books that satisfy the if condition and return it from the check method(the callback method). So, I tried to declare a variable outside the if condition and assign the output of the function to that variable(declared outside the if condition) .I also need to return the each book from the map function satisfying the condition.So,I have used an array to return both the values. But as I have mentioned in the comment, console.log(shelf) return an empty array.It shows undefined.What is the correct way to get both the values from the callback function? Can anyone please suggest me a solution?

pranami
  • 1,381
  • 5
  • 22
  • 43

1 Answers1

1

Your problem arises because you are using the setState callback syntax incorrectly. The second argument to setState is a callback function you are just executing the function

You need to write it like

this.setState({ books : book_search }, this.check);

Also console.log() after setState doen't show you the updated state values, you should write it in the callback

this.setState({books: book_result}, () => {console.log(this.state.books)})

Also make sure that you are returning the appropriate value from the handleSelfChange function

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Thanks for the answer.But the main issue is in returning the shelfChange variable which is running the handleShelfChange function which was sent as props from the parent component.Since the shelfChange variable is inside the if condition,I declared a variable outside the condition as shelf and assigned shelfChange to shelf.But I am not able to return shelf from the if condition.Actually I was talking about the console.log(selfChange) which shows as undefined. – pranami Nov 08 '17 at 06:05
  • As ok see your handleSelfChange function doesn't return anything so you get undefined – Shubham Khatri Nov 08 '17 at 06:11
  • ohh,okay.Now I understood.My handleShelfChange() method wasn't returning anything.And my problem was solved using the syntax that you provided for the callback function.I was using the brackets after the function while calling it.Thanks a lot for your help. :) – pranami Nov 08 '17 at 06:29
  • No problem, glad to have helped – Shubham Khatri Nov 08 '17 at 06:30
  • One more doubt I have.If you don't mind,will you please tell me how to update the parent component's state from a child component?I know we can pass the state from the parent component to the child as props, but is there any way to update the props back when some changes are happened in the child component's state? – pranami Nov 08 '17 at 06:39
  • See this, it will help you https://stackoverflow.com/questions/38394015/how-to-pass-data-from-child-component-to-its-parent-in-reactjs/38397755#38397755 . You need to pass a function in parent that updates state to the child as props and then call it from the child – Shubham Khatri Nov 08 '17 at 06:40