0

I have a button for rendering new components (actually charts, i have simplified the example to only show text) which adds a text to the page the first time it's clicked, but won't add any new text-objects to the page with further clicks.

I've tested to see if the function is actually running when I'm pressing it multiple times by making it add elements to an array which it does, so why isn't it rendering new text-objects to the page when clicked multiple times?

I might be missing something fundamental and would be grateful for any explanation.

import React from 'react';
import './App.css';

class NewChart extends React.Component {
  render() {
    return (
      <div>Text</div>
    );
  }
}

class Button extends React.Component {
  render() {
    return (
      <button {...this.props}>
        Add chart
      </button>
    );
  }
}

class ChartApp extends React.Component {
  constructor() {
    super();
    this.state = {
        clicked: false
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({
        clicked: true
    });
  }

  render() {
    return (
      <div>
        <Button onClick={this.handleClick} />
        {this.state.clicked ? <NewChart />: null}
      </div>
    );
  }
};

export default React.createClass({
  render: function () {
    return (
      <div>
        <ChartApp>
        </ChartApp>
      </div>
    )
  }
});
Facundo La Rocca
  • 3,786
  • 2
  • 25
  • 47

2 Answers2

0

You are presently using a button which sets a single flag to true, and then rendering a component when that flag is true. If you would like to render multiple components, you need some aspect of your state to relate to how many components you want to render, and then render based on that. For example as you mention, if you either use an array or perhaps a counter variable, you could then use either .map or even a for loop to render multiple components. Right now you're only asking React to conditionally render a single NewChart component.

John
  • 2,894
  • 2
  • 20
  • 25
  • So basically I'm pressing a button which stays down the whole time? – Henrik Halvorsen Mar 20 '17 at 19:15
  • Well, more like you're telling React "render this one thing if this var is true. When I click on this button, set it to true." What you'd want instead is something like "Render this component `n` times, and when I click on this button, increment `n`" – John Mar 20 '17 at 19:18
  • 1
    Oh, I think I understand now, thanks for the quick and to-point answer! – Henrik Halvorsen Mar 20 '17 at 19:24
0

The problem is that you are not adding new items, but just rendering or not depending on the value of checked. The trick is to have an array of elements to render and add one more element each time you click on the button.

Here you have an working example:

import React from 'react';
import './App.css';

class NewChart extends React.Component {
  render() {
    return (
      <div key={this.props.key}>Text</div>
    );
  }
}

class Button extends React.Component {
  render() {
    return (
      <button {...this.props}>
        Add chart
          </button>
    );
  }
}

class ChartApp extends React.Component {
  constructor() {
    super();
    this.state = {
      elements: []
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    var newArray = this.state.elements.slice();
    newArray.push(<NewChart key={this.state.elements.length + 1}/>);
    this.setState({
      elements: newArray
    });
  }

  render() {
    return (
      <div>
        <Button onClick={this.handleClick} />
        {this.state.elements.map((elem) => {
          return elem;
        })}
      </div>
    );
  }
}

class App extends React.Component {
  render () {
    return (
      <div>
        <ChartApp />
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
Facundo La Rocca
  • 3,786
  • 2
  • 25
  • 47
  • Sorry for late response. Although I've already solved the issue, thanks for the nice example, it seems to work great in my app as well and seemingly less code than i managed to slap together! – Henrik Halvorsen Mar 21 '17 at 13:38
  • No worries!! I'm glad to help you!! Would you mind to vote it up if it works? Thanks! – Facundo La Rocca Mar 21 '17 at 14:01
  • No can do, i require 15 rep which is something i don't have yet, sorry! Upvoted it nonetheless but says it won't change the publicity, however it is recorded. – Henrik Halvorsen Mar 22 '17 at 11:51