0

My problem is the following.

  • I have a "BookShelf" component which contains a "Book" list.
  • The parent (bookshelf) manage in its state a "selectedBook" property.
  • When clicking on one child (book), I would like to update its parent selectedBook property.
  • To achieve this, I use a function defined in the parent properties.
  • But this method is never trigerred (I tried with a console.log('something') but it never shows.

See my code below :

setSelectedBook(index) {
    this.setState({
        selectedBook: index
    })
},
getInitialState() {
    return {
        books: [],
        selectedBook: null
    }
},
componentDidMount() {
    let component = this
    $.ajax({
        url: 'data/books.json',
        success (data) {
            component.setState({
                books: data
            })
        },
        error (err) {
            console.log(err)
        }
    })
},
render() {
    let component = this
    var bookList = this.state.books.map(function(book, index) {
        let selectBook = component.setSelectedBook.bind(component, index)
        return (
             <Book onClick={selectBook} data={book} key={index} />
         )
    })
    return <div className="book-shelf">
        {bookList}
    </div>
}

Thanks in advance !

4
  • 1
    How your Book component triggers onClick? You need to trigger props.onClick() explicitly in Book component Commented Aug 4, 2016 at 14:44
  • Could you please paste the code for the Book component? Commented Aug 4, 2016 at 14:48
  • I may have missed something. The onClick isn't triggered only by adding it in the book declararation ? Commented Aug 4, 2016 at 14:48
  • 1
    @OhmWang onClick is just property on your custom component, react doesn't know what to do with it. Commented Aug 4, 2016 at 14:50

2 Answers 2

4

Here is a simple example for you. Also fiddle

You should pass your onClick event as a props to child component, once child component gets it, it will call a callback and pass an id as an agrument to the callback (like i have below).

class Book extends React.Component {
    constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    this.props.click(this.props.id)
  }
    render(){
    return  <li onClick={this.handleClick}>{this.props.id} - {this.props.name}</li>
  }
}

class BookShelf extends React.Component{
    constructor(){
    super();
    this.onClick = this.onClick.bind(this)
  }
  onClick(id){
    console.log(id)
  }
  render(){
    return <ul> // of course you may use Array.map functions, it's just for example
      <Book click={this.onClick} id={1} name={'hello'}/>
      <Book click={this.onClick} id={2} name={'world'}/>
    </ul>
  }
}

React.render(<BookShelf />, document.getElementById('container'));

Also i suggest look at this article Communicate Between Components, it will be useful for you.

Thanks

Sign up to request clarification or add additional context in comments.

Comments

1

select method return anonymous function as value.

<Book onClick={this.selectBook(index)} data={book} key={index} />

 selectBook (index){
       return ((() => {
            console.log(" selectBook fired" );
            component.setState({selectedBook:index}); 
              }).bind(component,index))
      
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.