0
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {  }
  }

  handleAddNew() {
    const name = prompt('What language do you want to add?')
  }

  render() { 
    return ( 
      <div className='container'>
        <h1>Please vote</h1>
        <Panel name='Python' />
        <Panel name='JavaScript' />
        <Panel name='PHP' />
        <Panel name='C#' />
                             <=============
        <button className='addNewButton' onClick={() => this.handleAddNew()}><h3>Add new</h3></button>
      </div>
     );
  }
}

I would like to add another call to the Panel component with the name variable in the handleAddNew function in the place that I have pointed to underneath the other Panel components.

Essentially when the button is clicked a prompt shows asking for the name of the desired language to be added and then creates a new component instance of Panel at the place of the arrow:

<Panel name={NAME_FROM_PORMPT} />     <=============

I assume this will use state and store the current votes for each panel which is stored in each Panel's state:

class Panel extends React.Component {
  constructor(props) {
    super(props);
    this.state = { voteCount: 0 }
  }

  handleClick() {
    this.setState({voteCount: this.state.voteCount + 1})
  }

  render() { 
    return ( 
      <div className='panel'>
        <span>
          <h3>{this.state.voteCount}</h3>
        </span>
        <span>
          <h3>{this.props.name}</h3>
        </span>
        <span>
          <button onClick={() => this.handleClick()}><h3>VOTE</h3></button>
        </span>
      </div>
     );
  }
}

I hope this makes sense and feel free to ask questions so that you are more able to help. Thanks in advance.

Edit: I added most of the code for context but my apologies if it is too complicated

1
  • Why not make the method handleAddNew a class variable that holds an arrow function? This way the browser doesn't have to create a new function on each render cycle and no bloated code is needed on the onClick param value. Arrow functions are transparent and have access to this. Commented Mar 14, 2021 at 16:34

2 Answers 2

2

If you maintain the list panels and render them using map will simplify. On adding new panel from prompt, Just update the state (panels list).

Try some thing like below.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { panels: ['Python', 'Javascript', 'PHP', 'C#'] }
  }

  handleAddNew() {
    const name = prompt('What language do you want to add?')
    this.setState({ panels: [...this.state.panels, name] })
  }

  render() { 
    return ( 
      <div className='container'>
        <h1>Please vote</h1>
        {this.state.panels.map(pan =>  <Panel key={pan} name={pan} />)}
        <button className='addNewButton' onClick={() => this.handleAddNew()}><h3>Add new</h3></button>
      </div>
     );
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I'd do: this.setState({panels: [...this.state.panels, name]}), saves 2 lines and extra code execution.
This would work but I also need to store how many votes each language has.
@FinHARRIS, You can change the panels state as Array of objects [{ name: 'C', votes: 0 }].
Yep that works. Just thought of it as I saw your message, thanks.
2

You are looking for something like this:

import React from "react";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { langs: ["Python", "JavaScript", "PHP", "C#"] };
  }

  handleAddNew() {
    const name = prompt("What language do you want to add?");
    this.setState({ langs: [...this.state.langs, name] });
  }

  render() {
    return (
      <div className="container">
        <h1>Please vote</h1>
        {this.state.langs.map((lang) => (
          <Panel name={lang} />
        ))}
        <button className="addNewButton" onClick={() => this.handleAddNew()}>
          <h3>Add new</h3>
        </button>
      </div>
    );
  }
}
export default App;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.