1

I'm currently building a form with React, and I'm wondering what the best practices are for pre-filling fields from an object.

import React, { Component } from 'react' class EditResourceForm extends Component { constructor (props) { super(props) this.state = { resource: props.resource } } handleFieldChanged (e) { // update state } render () { return ( <input type="text" value={this.state.resource.email} onChange={::this.handleFieldChanged} /> ) } } 

I'm encountering a problem when this.state.resource.email is null or undefined, because React does not want me providing those as values to controlled components:

Warning: `value` prop on `input` should not be null. Consider using the empty string to clear the component or `undefined` for uncontrolled components. 

Where is the proper place to provide an empty string as a fallback for a null value? Should this be done in the parent component's constructor method? Is there a way to avoid having to do this explicitly for every attribute that might have a null value?

1
  • 1
    Do it exactly as you're doing it now, just set resource: props.resource to resource: props.resource || {} so it doesn't throw an error if props.resource is empty. Commented Jan 31, 2017 at 20:47

2 Answers 2

1

Simplest way I can think of:

constructor (props) { super(props) this.state = { resource: props.resource || {} } } 

As far as I know there is no way to automatically set this values so they are not null, but if there was, I would not recommend it, good code is self explanatory.

EDIT 1

If this is still not enough, then the other option is using uncontrolled components, however, straight from the documentation of react:

Since an uncontrolled component keeps the source of truth in the DOM, it is sometimes easier to integrate React and non-React code when using uncontrolled components. It can also be slightly less code if you want to be quick and dirty. Otherwise, you should usually use controlled components.

EDIT 2

The code provided on the documentation seems a little convoluted, so here is a snippet of how I would do it:

<input type="text" onChange={(e, val) => {this.setState({email: val})}} /> 
Sign up to request clarification or add additional context in comments.

2 Comments

This is what I'm currently doing (however, setting the individual attributes of the resource object to empty strings if null). Becomes quite tedious with longer forms, because I have many values that must be explicitly provided.
If it is really tedious for you can use uncontrolled components, and update the state only on value change (facebook.github.io/react/docs/uncontrolled-components.html), but beware, read the page and you will realize it might not always be the best idea
0

You can use the defaultValue prop to set an initial value.

<input type="text" defaultValue={this.state.resource.email ? this.state.resource.email : ""} onChange={this.handleFieldChanged} /> 

Check out this great documentation about controlled vs uncontrolled components: https://facebook.github.io/react/docs/uncontrolled-components.html

1 Comment

I believe defaultValue is only available to uncontrolled inputs, and my form requires controlled components.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.