Qual é o comportamento atual?
Confirmado a partir de 0.14.7, mas também acontece hoje em 15.3.2.
https://jsfiddle.net/dimitar/7ktbfetb/
class Foo extends React.Component {
render(){
const handleChange = _.debounce(this.props.onChange, 500);
return <input onChange={handleChange} />
}
}
ReactDOM.render(<Foo onChange={e => console.log(e.target, e)} />, document.querySelector('div'));
espere receber e.target
, receba null
sem o debounce, funciona como esperado. https://jsfiddle.net/dimitar/7ktbfetb/1/
possivelmente relacionado a https://github.com/facebook/react/commit/3285d834402a60d241188a1deacf8250b50239cf - para https://github.com/facebook/react/blob/master/CHANGELOG.md#react -9
Para quem procura uma solução alternativa, você pode usar e.persist()
por exemplo. return <input onChange={e => handleChange(e.persist()||e)} />
Isso é por causa de como o debounce funciona. Ele usará setTimeout para enviar uma chamada para o próximo loop de eventos. Como você observou, por causa do pool, isso significa que o React já retornou o evento sintético de volta ao pool e redefiniu os campos. Se você estiver usando debounce ou qualquer outra coisa que exija que o evento exista fora do manipulador de eventos do React (por exemplo, código assíncrono), então você precisa persistir.
Isso é por design, então não há nada a fazer sobre isso agora. Há alguma discussão em #6190 sobre a possível remoção do pool, o que deve fazer seu código funcionar sem persistência explícita.
isso vai contra os próprios princípios de reação estabelecidos para resolver em torno do fluxo de dados, imutabilidade e evitar efeitos colaterais. você está passando um objeto para um componente, mas é apenas um instantâneo que deve ser usado no mesmo loop de eventos porque você desconfia do GC e dos usuários que podem criar inadvertidamente um vazamento ...
embora possa ter sido uma boa ideia na época, alguns de nós só precisam oferecer suporte a navegadores perenes que sejam capazes de GC adequado. talvez, enquanto essa abordagem está sendo reconsiderada, um sinalizador/env var pode ser definido para desativar o pooling.
Comentários muito úteis
Para quem procura uma solução alternativa, você pode usar
e.persist()
por exemplo.
return <input onChange={e => handleChange(e.persist()||e)} />