Hello! My question is very simple and affects the basic thing - rendering elements on the page. But to my surprise, I have not been able to find information on this issue for a long time.
I use ReactJS as a front-end framework.
Let's say I have a page with the simplest form: a field, the Add Field button and a Submit button. Attention a question: how to implement this button Add a field? When you click on that - another text field appears.
I'll tell you how I tried to solve this problem.
class IngredientForm extends Component { render() { return( <form onSubmit={this.handleSubmit.bind(this)}> <input type="text"/> { this.renderOtherInputs() } <input type="button" value="Add Ingredient" onClick={this.addIngredient.bind(this)}> <input type="submit" value="Submit Form"> </form> ); } } Here is the code for this form itself. When you click on the Add Ingredient button, another <input type="text> should appear.
How to do it? I know that the basis of Meteor is reactivity, so I don’t need to render anything directly. You need to rely on some kind of reactive data source and change it. And it will already cause changes to the interface.
In tutorials only one situation was considered - we have a collection, we need to display each document from the collection. That is, the reactive data source is a collection, we collapse it into an array, and then we draw an interface for each element of the array. Well, I decided to do likewise, but since the number of inputs on the page is a local state on the client, it will be wrong to store it in the collection. meteor has the answer - reactive var. we have:
numOfIngredients = new ReactiveVar([]); When we click on the Add field, the following method works:
addIngredient(e) { e.preventDefault(); let newNumOfIngredients = numOfIngredients.get(); newNumOfIngredients.push('no matter'); numOfIngredients.set(newNumOfIngredients); } Well, the method for rendering based on our jet array:
renderOtherInputs() { return numOfIngredients.get().map((elem) => { return( <input type="text"/> ); } } But the code does not work. I registered in the addIngredient console.log(numOfIngredients.get()) method console.log(numOfIngredients.get()) and when I clicked on the add field button, the correct behavior was output to the console:
['no matter'] ['no matter','no matter'] ['no matter','no matter','no matter'] ... However, the field does not appear. I tried and with createContainer to do, declaring numOfIngredients = new ReactiveVar([]); there, and then referring to it as this.props.numOfIngredients.get() . The array is filled, the console is displayed, input does not appear. Perhaps my decision is inherently wrong and crutch.
I really hope for the help of the community, especially since I have a simple question, as it seems to me. Thanks in advance for your answers!