Reputation: 1714
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
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
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
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