David Johns
David Johns

Reputation: 1714

How to append a dynamic HTML element to React component using JSX?

I'm new to Reactjs. I'm creating an App with a Survey creation like Google Forms. My component has a button to create a new Div with some HTML elements to create a survey question. To do that, on the button click function, I'm creating a JSX element and push it to an array. And then, I set the array inside the render function to display what inside it.

The problem is, Even though the Array is updating, the dynamic HTML part can not be seen on the page. The page is just empty except the button. How can I fix this?

Component:

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

let questionId = 0;

class SurveyCreation extends Component {
    constructor(props) {
        super(props);
        this.questionsList = [];
        this.state = {

        }
    }

    addQuestion = (e) => {
        e.preventDefault();

        questionId = questionId + 1;

        this.questionsList.push(
            <div key={questionId}>
                question block
            </div>
        )
    }

    render() {

        return (
            <div>
                <button onClick={e => this.addQuestion(e)}>Add Question</button>
                <div>
                    {this.questionsList}
                </div>
            </div>
        );
    }
};

export default SurveyCreation;

Upvotes: 2

Views: 1801

Answers (3)

angelCanales
angelCanales

Reputation: 97

You need to map your this.questionsList variable.

You can save the 'question string' in the array and then iterate the array printing your div.. Something like this.

<div>
    {this.state.questionsList.map(questionString, i => (
      <div key={i}>
        {questionString}
      </div>
    )}
</div>

Upvotes: 1

dmiranda2791
dmiranda2791

Reputation: 21

I think you're component is not re-rendering after you fill the array of elements.

Try adding the questionsList to the component's state and modify your addQuestion method so that it creates a new array, finally call setState with the new array.

Upvotes: 1

Nicholas Tower
Nicholas Tower

Reputation: 84902

The only way a react component knows to rerender is by setting state. So you should have an array in your state for the questions, and then render based on that array. In the array you want to keep data, not JSX elements. The elements get created when rendering.

constructor(props) {
  super(props);
  this.state = {
    questions: [],
  }
}

addQuestion = () => {
  setState(prev => ({
     // add some object that has the info needed for rendernig a question. 
     // Don't add jsx to the array
    questions: [...prev.questions, { questionId: prev.questions.length }];
  })
}

render() {
  return (
    <div>
      <button onClick={e => this.addQuestion(e)}>Add Question</button>
      <div>
        {this.state.questions.map(question => (
          <div key={question.questionId}>

          </div>
        )}
      </div>
    </div>
  );
}

Upvotes: 5

Related Questions