Austin Witherow Austin Witherow - 16 days ago 12
React JSX Question

Resetting Values in ReactDOM Ref children (Best Practices?)

I've got a stateless component, called FlexibleInput.

import React, { PropTypes } from 'react'

export default function FlexibleInput({
id,
label,
defaultValue,
type,
onChange,
}){
let fieldClass = `${id}-field`
return (
<fieldset className={fieldClass}>
<label htmlFor={id}>{label}</label>
<input
key={id}
id={id}
type={type}
defaultValue={defaultValue}
onChange={onChange}
/>
</fieldset>
)
}

FlexibleInput.propTypes = {
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
defaultValue: PropTypes.string.isRequired,
type: PropTypes.string.isRequired, // accepts "text", "password" atm.
onChange: PropTypes.func.isRequired,
}


I use this FlexibleInput in a form called AddNote.

<form
className="note-list__add-note"
onSubmit={this.addNote}
ref={`${this.props.type}-addNoteForm`}
>
<FlexibleInput
id="note"
label="Awaiting changes..."
type="text"
defaultValue=""
onChange={(e) => this.setState({ content: e.target.value })}
/>


After submitting using the this.addNote function... I would like to be able to reset the FlexibleInput input value.

I've managed to do a ugly ass hack version...

this.refs[`${this.props.type}-addNoteForm`]
.childNodes[0].childNodes[1].value = ''


Which manages to properly reset the value. This is prone to change because perhaps the structure of the FlexibleInput will change? I do not know, hopefully not.

But my main question is, is there a way that I could do a sort of

this.refs[bla bla].find(#input)


or so?

It is not very clear in the React/ReactDOM documentation which api is available for a
ref
.

Thank you!

Answer

You could create a Controlled component whereby the value of the input is set using using component state:

<form
  className="note-list__add-note"
  onSubmit={this.addNote}
  ref={`${this.props.type}-addNoteForm`}
  >
  <FlexibleInput
    id="note"
    label="Awaiting changes..."
    type="text"
    defaultValue=""
    value={this.state.content}
    onChange={(e) => this.setState({ content: e.target.value })}
  />

Then you just need to reset the content value within the this.addNote method:

addNote() {
  this.setState({ content: '' });
}

N.B. Ensure you bind addNote correctly to ensure this.setState is correctly referenced.