I’m new to meteor and react. Let’s say I have this in my react component:
getMeteorData() {
var myForm = ProjectForm.findOne({_id:this.props.router.params._id});
var projects = ProjectForm.find({});
return {myForm:myForm,projects:projects};
// doing a console.log(myForm); would give you something like
/*
input1:my text 1
input2:some other text
input3:something else
etc....
*/
},
renderListProjects() {
return this.data.projects.map(function(projectform,i) {
return <li key={"li"+i}><a href={Meteor.absoluteUrl()+'project/' + projectform.username +'/' +projectform._id} key={"a"+i}>Project {projectform._id}</a></li>;
});
},
getInitialState() {
return Projects.findOne({this.props.router.params._id}, {sort: {createdAt: -1}});
},
render() {
return (
<div>
<ul>{this.renderListProjects()}</ul>
<form>
<span>Hello this is some text</span>
<input type="text" ref="input1" />
<p>Blah blah this is boring</p>
<input type="text" ref="input2" />
<img src="image-of-a-kangaroo.png" />
<input type="text" ref="input3" />
<ul>
<li>Buy brocolli</li>
<li>Buy oregano</li>
<li>Buy milk</li>
</ul>
<input type="text" ref="input4" />
...
<textarea ref="input100"></textarea>
<input type="text" ref="input101" />
<p><strong>Yes, I like pizza!</strong> But my porcupine gets sick eating pizza.</p>
...
</form>
</div>
);
What I want to do is assign the values of this.data.myForm
to each of the form fields in the render() function. But when I do something like <input type="text" ref="input1" value={this.data.myForm.input1} />
, and I go to my web browser and put my cursor on that field, I am NOT able to modify the value. Pressing the keys on my keyboard will not change the value of that input field. Additionally, I have about 250 input fields in this html form. I really don’t want to do any data entry. I would much rather just use some kind of loop to iterate through the this.data.myForm
and assign it to the corresponding form fields. But when I tried to do this, I get problems about the DOM not being found or it’s not loaded. So I tried writing some code in componentDidMount(), but then I got other errors.
Can anyone point me in the right direction on how to efficiently bind all my this.data.myForm
data to my form fields AND allow me to edit the form fields after?
Additional Requirements
-
If someone clicks on link1 from the
renderListProjects
then clicks on link2 from therenderlistProjects
, then the form must show the value of link2’sprojectform._id
. -
In the DOM, an
href="project/_id"
attribute must exist for SEO and for WCAG compliance.
Attempts
I tried to redefine renderListProjects as
renderListProjects() {
var pj = this
return this.data.projects.map(function(projectform,i) {
return <li key={"li"+i}><a onClick={pj.click(projectform._id)} href={Meteor.absoluteUrl()+'project/' + projectform.username +'/' +projectform._id} key={"a"+i}>Project {projectform._id}</a></li>;
});
},
click(id) {
var currentApp = ProjectForm.findOne({_id:id}, {sort: {createdAt: -1}});
this.setState({input36:input36});
},
But when I run my meteor+react project, my browser crashes because some kind of infinite loop is happening.
2
Answers
This code solved the problem
To summarize, my changes were:
renderListProjects()
functionclickLoadForm()
function and used it in therenderListProjects()
handleChange()
function and made sure it's references via onChange for each element inrender()
render()
has an id that's the same as the refWhat you created is what React calls an controlled input. This means that React has declared your value in the inputs to correspond to whatever
this.data.myForm.input1
points to.What you need to do in order to be able to change an input field is to add an onChange handler that takes care of updating the value. The documentation is quite straight forward but I added a small example below to illustrate it.