HikingGuru
HikingGuru

Reputation: 11

onClick button calling a method of another component

I have a button in one of my components. By clicking it I want to render all the items of a list on the page. Without the button if i just write {this.functionName}, I can see all the items on the page but when i write

<input type="submit" value="press" onClick={this.functionName} />

I cant see anything. I tried to bind it to this in different ways and didn't work. Also i thought i might move the button to the homepage and under <Component/>

<input type="submit" value="press" onClick={Component.functionName} />   

However it didnt work. the only thing that i noticed by replacing Component.functionName by console.log('sth') is that without clicking any refresh, "sth" prints to the console

I have already checked the site, and tried any answer that i could find but it didn't work. The component is :

module.exports = React.createClass({
mixins: [
    Reflux.listenTo(TopicStore, 'onChange')
],
getInitialState: function(){
    return{
     topics: []
    }
},  

render: function(){
    return <div className="list-group">
    TopicList
    {this.renderTopics()}

</div>
},

renderTopics: function(){
    return this.state.topics.map(function(topic){
        return <li>
            {topic}
        </li>
    });
},

this one works fine and lists all the items in the topics on the page but if i replace {this.renderTopics}with the "input" one doesnt work any more

Upvotes: 1

Views: 1875

Answers (3)

sandeepdhakal
sandeepdhakal

Reputation: 81

Your component is not displaying the topics because the input button's onClick method generates the list but doesn't re-render the component.

Your component's state should have a toggle to display the list (or not display). The input's onClick should toggle the component's state which will lead to the component being re-rendered.

class TopicList extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      showTopics: false
    }
    this.toggleTopics = this.toggleTopics.bind(this)
  }

  toggleTopics() {
    this.setState({showTopics: !this.state.showTopics})
  }

  renderTopics() {
    return this.props.topics.map(x => 
      <li key={x}>{x}</li>
    )
  }

  render() {
    return (
    <div>
      <input type='submit' value='press' onClick={this.toggleTopics} />
      <ul>
        {this.state.showTopics && this.renderTopics()}
      </ul>
    </div>
    )
  }
}

Also, don't forger to give the li tags a key property.

Upvotes: 0

OlehZiniak
OlehZiniak

Reputation: 953

OK, without diving deep into your code, I suggest you to try something like this

module.exports = React.createClass({
mixins: [
    Reflux.listenTo(TopicStore, 'onChange')
],

showTopics: false,

getInitialState: function(){
    return{
     topics: []
    }
},  

render: function(){
    return (
        <div className="list-group">
          TopicList
          <button onClick={this.toggleTopics()}>Show Topics</button>
          {this.showTopics && this.renderTopics()}
       </div>
    )
},

toggleTopics: function() {
    this.showTopics = !this.showTopics;
},

renderTopics: function(){
    return this.state.topics.map(function(topic){return <li>{topic}</li>});
},

Watch out that trailing comma at the end, I tried to keep the structure of the code you've provided at the question.

Upvotes: 0

Piyush.kapoor
Piyush.kapoor

Reputation: 6803

use button instead of input and use bind

<button type="submit" value="press" onClick={this.functionName.bind(this)} />

Upvotes: 1

Related Questions