Considere este ejemplo:
var Field = React.createClass({ render: function () { // never renders new value... return ( <div> <input type="text" defaultValue={this.props.value || ''} /> </div> ); } }); var App = React.createClass({ getInitialState: function () { return {value: 'Hello!'}; }, changeTo: function (str) { this.setState({value: str}); }, render: function () { return ( <div> <Field value={this.state.value} /> <button onClick={this.changeTo.bind(null, 'Whyyyy?')}>Change to "Whyyyy?"</button> <button onClick={this.changeTo.bind(null, void 0)}>Change to undefined</button> </div> ); } }); React.render( <App />, document.getElementById('app') ); Quiero pasar el valor a defaultValue como accesorio del componente de entrada tonto. Sin embargo, nunca lo vuelve a renderizar.
Como se mencionó en una respuesta anterior, defaultValue solo se establece en la carga inicial de un formulario. Después de eso, no se actualizará "naturalmente" porque la intención era solo establecer un valor predeterminado inicial.
Puede evitar esto si lo necesita pasando una key al componente contenedor, como en su componente Field o App , aunque en circunstancias más prácticas, probablemente sería un componente de form . Una buena key sería un valor único para el recurso que se pasa al formulario, como la identificación almacenada en la base de datos, por ejemplo.
En su caso simplificado, podría hacer esto en su representación de campo:
<div key={this.props.value}> <input type="text" defaultValue={this.props.value || ''} /> </div>En un caso de formulario más complejo, algo como esto podría obtener lo que desea si, por ejemplo, su acción onSubmit se envió a una API pero permaneció en la misma página:
const Form = ({item, onSubmit}) => { return ( <form onSubmit={onSubmit} key={item.id}> <label> First Name <input type="text" name="firstName" defaultValue={item.firstName} /> </label> <label> Last Name <input type="text" name="lastName" defaultValue={item.lastName} /> </label> <button>Submit!</button> </form> ) } Form.defaultProps = { item: {} } Form.propTypes = { item: PropTypes.object, onSubmit: PropTypes.func.isRequired }Cuando usamos entradas de formulario no controladas, generalmente no nos preocupamos por los valores hasta después de que se envían, por eso es más ideal forzar solo una nueva representación cuando realmente desea actualizar los valores predeterminados (después de enviar, no en cada cambio de la entrada individual).
Si también está editando el mismo formulario y teme que la respuesta de la API pueda devolverse con valores diferentes, puede proporcionar una clave combinada de algo como id más marca de tiempo.
defaultValue solo funciona para la carga inicial. Después de eso, no se actualizará. Debe mantener el estado de su componente de campo :
var Field = React.createClass({ //transfer props to state on load getInitialState: function () { return {value: this.props.value}; }, //if the parent component updates the prop, force re-render componentWillReceiveProps: function(nextProps) { this.setState({value: nextProps.value}); }, //re-render when input changes _handleChange: function (e){ this.setState({value: e.target.value}); }, render: function () { // render based on state return ( <div> <input type="text" onChange={this._handleChange} value={this.state.value || ''} /> </div> ); } });Estoy bastante seguro de que esto tiene que ver con las entradas controladas frente a las no controladas.
Si lo entiendo correctamente, dado que su <input> no está controlado (no define un atributo de value ), entonces el valor siempre se resolverá en el valor con el que se inicializó. En este caso Hello! .
Para superar este problema, puede agregar un atributo de value y configurarlo durante onChange :
var Field = React.createClass({ render: function () { // never renders new value... return ( <div> <input type="text" defaultValue={this.props.default || ''} value={this.props.value} /> </div> ); } });Aquí hay un plunker que muestra el cambio.