React 中 input 的 onChange 事件 e 参数传递之后 e.target 变为 null

本文探讨了在React中使用input组件onChange事件时遇到的一个问题:当使用防抖函数(debounce)时,e.target在fetchAjax中变为null。通过分析,发现原因是事件处理函数changeValue执行后,React的事件清理机制导致event.target被释放。解决方案是将event.target的值保存到局部变量,避免直接引用event.target。文章总结了该问题涉及的内存释放、引用类型和事件处理知识点。

github 的地址 欢迎 star

前言

小明遇到了一个需求:在 input 框 change 的时候发起一个异步请求,对于请求一般做法都要防抖,但是却遇到了取不到 value 的值的情况。 简化代码可以查看 这里 关键代码:

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Input } from "antd";
import _ from "lodash";
const changeValue = e => {
  const value = e.target.value;
  console.log("sdj", e);
  console.log("sdj", value);
  const debugeDebounce = _.debounce(() => {
    fetchAjax(e);
    // fetchAjax(value);
  }, 900);
  debugeDebounce();
};

const fetchAjax = e => {
  console.log("sdj222", e);
};

ReactDOM.render(
  <Input placeholder="Basic usage" onChange={changeValue} />,
  document.getElementById("container")
);

复制代码

在 fetchAjax 中取到的 e.target 为 null 的情况,在其中经过断点调试,发现了其中的缘由。

首先,在 changeValue 中,事件触发,就能获取到 event 对象,其中主要就是 event.target 就是当前触发事件的 dom 对象,由于 debounce 延迟执行,导致了 changeValue 函数已经执行完了,进入了 react-dom 中相关一系列操作(进行了一系列复杂的操作),下面给出最关键的 executeDispatchesAndRelease,executeDispatchesAndRelease 方法释放 event.target 的值

        /**
 * Dispatches an event and releases it back into the pool, unless persistent.
 *
 * @param {?object} event Synthetic event to be dispatched.
 * @private
 */
        var executeDispatchesAndRelease = function(event) {
            if (event) {
                executeDispatchesInOrder(event);
                if (!event.isPersistent()) {
                    event.constructor.release(event);
                }
            }
        };
复制代码

具体的可以自己断点查看相关 event 的值的变化

由于 event 在 debounce 中作为了参数,内存中没有清除,执行上面的方法 event.target = null; event 为引用类型,一处改变,所有用到的地方都会改变。导致了 debounce 中 event 也发生了变化。

解决

明白了上面的一些知识,就知道应该怎么修改代码了(把用到的值存在一个变量中)

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Input } from "antd";
import _ from "lodash";
const changeValue = e => {
  const value = e.target.value;
  console.log("sdj", e);
  console.log("sdj", value);
  const debugeDebounce = _.debounce(() => {
  
    -- fetchAjax(e);
    ++ fetchAjax(value);
    
  }, 900);
  debugeDebounce();
};

const fetchAjax = e => {
  console.log("sdj222", e);
};

ReactDOM.render(
  <Input placeholder="Basic usage" onChange={changeValue} />,
  document.getElementById("container")
);

复制代码

总结

工作中的一些问题还是值得去挖掘的,总会有一定的收获!这个问题中包括了内存释放,引用类型,事件等

如果有错误或者不严谨的地方,请务必给予指正,十分感谢!

参考

  1. stackoverflow.com/questions/2…
  2. developer.mozilla.org/zh-CN/docs/…
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值