3

So let's say I have a react component that's being rendered like this:

<Form /> 

In this case, inside Form, this.props.children is undefined.

However, inside render, I have the following:

render: function() { return ( <form> <input name='foo' /> <input name='bar' /> </form> ) } 

It would be easy to access 'foo' and 'bar' by using the ref keyword. However, this is not flexible/reusable when I have a lot of "children" (that I can't access with this.props.children or React.Children.forEach because they're not "children")

I would like to loop through all the child components that are in render without having to give a ref for each one. (If I give a ref, I would be able to loop through this.refs)

Is this possible?

6
  • Is there any reason you want to loop through the inputs ? Commented Aug 17, 2015 at 13:47
  • @Harish certainly. I have <Input> components that I have created that have a "valid" state. I want to loop through all of them to determine if the state of the form is valid. Commented Aug 17, 2015 at 16:16
  • Have you considered centralization of the form's state or bubbling it to the host component rather than looping through the children? Commented Aug 19, 2015 at 10:37
  • @WiredPrairie yup.. Let's consider the child's state in this case. It's either valid or invalid. When it's changes state and notifies the parent, the parent still needs to know the states of all the children in order to determine whether the form can be submitted. Also, think about nested components, I would need to bubble up many levels or implement flux, which I don't think is the best way to go here. The most reusable way I think is a validatable form that can take React components tagged with a valid state. Parents recursively checks all children and determine validity. Commented Aug 19, 2015 at 12:32
  • React is designed to be one-way data flow (with events being a way for notification). So, for a parent to loop "multiple levels" through children to evaluate validity seems like it may not be the best React pattern. You don't need to implement Flux to have centralized data. You could pass an object that had some methods that could be used to indicate the validity of a component for example. Commented Aug 19, 2015 at 14:22

1 Answer 1

3

Before getting to an answer, a bit of terminology clarification: Those input elements are part of the DOM for Form; they are not child components (at least not in Reactjs parlance).

A common solution to your problem is to convert those input elements into React Input components so that you can access them using this.props.children. You would have an "implementation" form that contains both the generic Form component and all the Input components. It would look something likes this

<MyForm> <GenericForm> <Input name='foo' /> <Input name='bar' /> </GenericForm> </MyForm> 

In this example, GenericForm can iterate over this.props.children to access the foo and the bar Inputs

Note that MyForm exists simply to encapsulate the entire form and allow you to re-use that specific form as a single component. I only included it because your example has Form as a single entity. If you are only using the form in a single place, you don't really need MyForm.

Sign up to request clarification or add additional context in comments.

2 Comments

So you're suggesting to have an intermediary child which role is to only hold children? This sounds like an OK solution I think. Let me give it a shot =) As for the terminology, yes, <Form /> has no this.props.children on purpose.
What would I do if my form were to generate its children? E.g. a list of input 1, 2, 3, ... Is there a way for it to set its own children?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.