現在の動作は何ですか?
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)} />
これは、デバウンスがどのように機能するかによるものです。 setTimeoutを使用して、呼び出しを次のイベントループにプッシュします。 お気づきのように、プールのため、これはReactがすでに合成イベントをプールに戻し、フィールドをリセットしていることを意味します。 デバウンスなど、Reactのイベントハンドラーの外部にイベントが存在する必要があるもの(非同期コードなど)を使用している場合は、永続化する必要があります。
これは仕様によるものであるため、現時点ではこれについて何もする必要はありません。 #6190には、プーリングを削除する可能性についての議論があります。これにより、明示的に永続化することなくコードを機能させることができます。
これは、データの流れ、不変性、および副作用の回避を解決するために設定されたまさに原則に反します。 オブジェクトをコンポーネントに渡しますが、誤ってリークを作成する可能性のあるGCとユーザーを信用しないため、同じイベントループ内で使用する必要があるのはスナップショットのみです...
当時は良い考えだったかもしれませんが、適切なGCが可能な常緑のブラウザのみをサポートする必要がある人もいます。 おそらく、このアプローチが再検討されている間、フラグ/環境変数を設定してプーリングをオフにすることができます。
最も参考になるコメント
回避策を探している人は、
e.persist()
を使用できます。例えば。
return <input onChange={e => handleChange(e.persist()||e)} />