6

I've used React for a couple of weeks now but I have this simple problem that I can't seem to wrap my head around. It's about creating new html elements.

I would just like to know in general if the way that I went about it, is the "right way" or is there another preferred way to create new html element with a click function.

For some reason this problem took awhile for me to figure out and it still feels a bit strange, that's why I'm asking.

Thanks in advance!

import React, { Component } from 'react';
import './Overview.css';

import Project from './Project';

class Overview extends Component {
 constructor() {
  super()
  this.state = {
   itemArray: []
  }
}

createProject() {
 const item = this.state.itemArray;
 item.push(
   <div>
     <h2>Title</h2>
     <p>text</p>
   </div>
 )
 this.setState({itemArray: item})
 //console.log(this.state)
}

render() {
 return (
   <div className="Overview">
     <p>Overview</p>
     <button onClick={this.createProject.bind(this)}>New Project</button>
     <Project />
     <div>
       {this.state.itemArray.map((item, index) => {
         return <div className="box" key={index}>{item}</div>
       })}
     </div>
   </div>
  );
 }
}

export default Overview;

1 Answer 1

10

No, this is not a correct approach. You shouldn't be generating HTML elements like that, nor keep them in state - it is against React to manipulate DOM like that. You won't be able to utilize Virtual DOM is the first thing that I can think of.

What you should do instead is keep all data that is needed for rendering in state and then generate the HTML element from there, for instance

createProject() {
  const item = this.state.itemArray;
  const title = '';
  const text = '';
  item.push({ title, text })
  this.setState({itemArray: item})
}

render() {
  return (
    <div className="Overview">
      <p>Overview</p>
      <button onClick={this.createProject.bind(this)}>New Project</button>
      <Project />
      <div>
        {this.state.itemArray.map((item, index) => {
          return (
            <div className="box" key={index}>
                <div>
                 <h2>{item.title}</h2>
                 <p>{item.text}</p>
               </div>
            </div>
          )
        })}
      </div>
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

3 Comments

Ok! Thanks for the explanation I appreciate it :)
Glad I could help;-)
Clean Solution! I like it :)

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.