Каково текущее поведение?
Подтверждено в 0.14.7, но также происходит сегодня в 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'));
ожидайте получить e.target
, получите null
без дребезга работает как положено. https://jsfiddle.net/dimitar/7ktbfetb/1/
возможно, связано с https://github.com/facebook/react/commit/3285d834402a60d241188a1deacf8250b50239cf - для https://github.com/facebook/react/blob/master/CHANGELOG.md#react -9
Для тех, кто ищет обходной путь, вы можете использовать e.persist()
например. return <input onChange={e => handleChange(e.persist()||e)} />
Это из-за того, как работает debounce. Он будет использовать setTimeout для отправки вызова в следующий цикл обработки событий. Как вы заметили, из-за объединения это означает, что React уже вернул синтетическое событие обратно в пул и сбросил поля. Если вы используете debounce или что-то еще, что требует, чтобы событие существовало за пределами обработчика событий React (например, асинхронный код), вам нужно сохраниться.
Это по замыслу, так что сейчас с этим ничего не поделаешь. В #6190 обсуждается потенциальное удаление пула, что должно заставить ваш код работать без явного сохранения.
это противоречит самим принципам реакции, направленным на решение проблемы потока данных, неизменности и предотвращения побочных эффектов. вы передаете объект компоненту, но это только моментальный снимок, который должен использоваться в том же цикле событий, потому что вы не доверяете GC и пользователям, которые могут непреднамеренно создать утечку...
хотя в то время это могло быть хорошей идеей, некоторым из нас нужно поддерживать только вечнозеленые браузеры, которые способны к адекватному сборщику мусора. возможно, пока этот подход пересматривается, флаг/env var может быть установлен для отключения объединения.
Самый полезный комментарий
Для тех, кто ищет обходной путь, вы можете использовать
e.persist()
например.
return <input onChange={e => handleChange(e.persist()||e)} />