Encontré este problema al crear una aplicación web y la replique en este jsfiddle . Esencialmente, me gustaría que una entrada llame a this.setState({message: input_val}) cada vez que escribo algo en él, luego lo paso a la clase de aplicación principal que luego vuelve a mostrar el mensaje en la clase de mensaje. Sin embargo, la salida parece estar siempre un paso por detrás de lo que realmente escribo. La demostración de jsfiddle debería explicarse por sí misma. Me pregunto si hice algo mal para provocar esto.
html
<script src="http://facebook.github.io/react/js/jsfiddle-integration.js"></script> <div id='app'></div>js
var App = React.createClass({ getInitialState: function() { return {message: ''} }, appHandleSubmit: function(state) { this.setState({message: state.message}); console.log(this.state.message); }, render: function() { return ( <div className='myApp'> <MyForm onChange={this.appHandleSubmit}/> <Message message={this.state.message}/> </div> ); } }); var MyForm = React.createClass({ handleSubmit: function() { this.props.onChange(this.state); }, handleChange: function(e) { console.log(e.target.value); this.setState({message: e.target.value}); this.handleSubmit(); }, render: function() { return ( <form className="reactForm" onChange={this.handleChange}> <input type='text' /> </form> ); } }); var Message = React.createClass({ render: function() { return ( <div className="message"> <p>{this.props.message}</p> </div> ) } }); React.render( <App />, document.getElementById('app') );Una llamada a setState no es síncrona. Crea una "transición de estado pendiente". (Ver aquí para más detalles). Debe pasar explícitamente el nuevo valor de input como parte del evento que se genera (como handleSubmit en su ejemplo).
Vea este ejemplo.
handleSubmit: function(txt) { this.props.onChange(txt); }, handleChange: function(e) { var value = e.target.value; this.setState({message: value}); this.handleSubmit(value); },Hay una manera mucho más simple de hacer esto, setState(updater, callback) es una función asíncrona y toma la devolución de llamada como segundo argumento,
Simplemente pase handleSubmit como una devolución de llamada al método setState , de esta manera, después de que se complete setState, solo se ejecutará handleSubmit .
Por ej.
handleChange: function(e) { console.log(e.target.value); this.setState({message: e.target.value}, this.handleSubmit); }Intente cambiar el método handleChange() como el anterior y funcionará.
para ver la sintaxis de usar setState , consulte este enlace
Estuve tirándome de los pelos durante una hora debido a esto, así que decidí compartir... Si su devolución de llamada todavía está un paso atrás y aparentemente no funciona, asegúrese de no LLAMAR a la función entre paréntesis... Solo pásela en. Error de novato.
DERECHO:
handleChange: function(e) { console.log(e.target.value); this.setState({message: e.target.value}, this.handleSubmit); }contra
EQUIVOCADO:
handleChange: function(e) { console.log(e.target.value); this.setState({message: e.target.value}, this.handleSubmit()); }