💥React 事件绑定与响应:从“懵圈”到“秒懂”,附 5 个实战技巧

面试官:"React 事件绑定怎么写?"

你:"onClick={this.handleClick}。"

面试官:"this 指向呢?"

你:"......"

别怕,今天把 React 事件绑定的坑全填掉!


一、React 事件绑定:3 种写法

1️⃣ 绑定方法(类组件)

jsx 复制代码
class Demo extends React.Component {
  handleClick = () => {
    console.log('Clicked!');
  };

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}
  • 箭头函数 :自动绑定 this,最省心。

2️⃣ 绑定实例方法(类组件)

jsx 复制代码
class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    console.log('Clicked!');
  }

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}
  • bind:在构造函数里绑定,适合普通函数。

3️⃣ 函数组件 + 事件处理

jsx 复制代码
function Demo() {
  const handleClick = () => {
    console.log('Clicked!');
  };

  return <button onClick={handleClick}>Click me</button>;
}
  • 函数组件:直接定义函数,简洁明了。

二、事件对象:e 是谁?

jsx 复制代码
function handleChange(e) {
  console.log(e.target.value); // 拿到输入框的值
}

function Demo() {
  return <input onChange={handleChange} />;
}
  • e合成事件对象,类似原生事件,但跨浏览器。

三、事件委托:少写 80% 的绑定代码

jsx 复制代码
function Demo() {
  const handleChildClick = (id) => {
    console.log(`Child ${id} clicked`);
  };

  return (
    <ul onClick={(e) => handleChildClick(e.target.dataset.id)}>
      <li data-id="1">Item 1</li>
      <li data-id="2">Item 2</li>
    </ul>
  );
}
  • 利用 e.target,在父级统一处理子级事件。

四、防抖节流:输入框的性能救星

防抖(Debounce)

jsx 复制代码
function useDebounce(callback, delay) {
  const timer = useRef(null);

  const debouncedCallback = useCallback((...args) => {
    clearTimeout(timer.current);
    timer.current = setTimeout(() => callback(...args), delay);
  }, [callback, delay]);

  return debouncedCallback;
}

function Demo() {
  const handleChange = useDebounce((e) => {
    console.log('Typing:', e.target.value);
  }, 500);

  return <input onChange={handleChange} />;
}

节流(Throttle)

jsx 复制代码
function useThrottle(callback, limit) {
  const lastCall = useRef(Date.now());

  const throttledCallback = useCallback((...args) => {
    const now = Date.now();
    if (now - lastCall.current >= limit) {
      callback(...args);
      lastCall.current = now;
    }
  }, [callback, limit]);

  return throttledCallback;
}

function Demo() {
  const handleChange = useThrottle((e) => {
    console.log('Typing:', e.target.value);
  }, 500);

  return <input onChange={handleChange} />;
}

五、事件穿透:阻止冒泡,让父级"看不见"

jsx 复制代码
function Demo() {
  const handleClick = (e) => {
    e.stopPropagation(); // 阻止冒泡
    console.log('Inner clicked');
  };

  const handleOuterClick = () => {
    console.log('Outer clicked');
  };

  return (
    <div onClick={handleOuterClick}>
      Outer
      <div onClick={handleClick}>Inner</div>
    </div>
  );
}

六、自定义事件:给组件加"私有信号"

jsx 复制代码
const EventEmitter = () => {
  const listeners = useRef({});

  const on = (eventName, callback) => {
    listeners.current[eventName] = listeners.current[eventName] || [];
    listeners.current[eventName].push(callback);
  };

  const emit = (eventName, ...args) => {
    const eventListeners = listeners.current[eventName] || [];
    eventListeners.forEach((listener) => listener(...args));
  };

  return { on, emit };
};

function Child() {
  const { emit } = useContext(EventEmitterContext);

  const handleCustomEvent = () => {
    emit('customEvent', 'Hello from Child!');
  };

  return <button onClick={handleCustomEvent}>Trigger Custom Event</button>;
}

function Parent() {
  const { on } = useContext(EventEmitterContext);

  useEffect(() => {
    on('customEvent', (message) => {
      console.log('Custom event received:', message);
    });
  }, [on]);

  return <Child />;
}

七、总结:React 事件绑定速记卡

场景 写法
类组件绑定 this.handleClick = this.handleClick.bind(this); 或箭头函数
函数组件 const handleClick = () => { ... };
事件对象 e.target.value 拿值
事件委托 e.target.dataset.id 读属性
防抖 useDebounce(callback, delay)
节流 useThrottle(callback, limit)
阻止冒泡 e.stopPropagation()
自定义事件 emit('eventName', data) + on('eventName', callback)

🏁 一句话总结

React 事件绑定:类组件用箭头函数或 bind,函数组件直接定义;事件对象用 e.target;防抖节流优化输入框;阻止冒泡控制事件范围;自定义事件跨组件通信。把这张表贴在工位,面试再也不怕问事件绑定!


相关推荐
典学长编程几秒前
前端开发(HTML,CSS,VUE,JS)从入门到精通!第五天(jQuery函数库)
javascript·css·ajax·html·jquery
野区小女王4 分钟前
react调用接口渲染数据时,这些表格里的数据是被禁选的
前端·react.js·前端框架
尝尝你的优乐美21 分钟前
原来前端二进制数组有这么多门道
前端·javascript·面试
前端_yu小白24 分钟前
Vue2实现docx,xlsx,pptx预览
开发语言·javascript·ecmascript
金金金__39 分钟前
事件循环-原理篇
javascript·浏览器
CF14年老兵40 分钟前
🔥 2025 年开发者必试的 10 款 AI 工具 🚀
前端·后端·trae
张元清1 小时前
解密苹果最新 Liquid Glass 效果:如何用代码重现 iOS 设计系统的视觉魔法
前端·css·面试
CF14年老兵1 小时前
2025 年 React 在 Web 开发中的核心地位:优势、应用场景与顶级案例
javascript·react.js·redux
还是大剑师兰特1 小时前
Javascript面试题及详细答案150道之(046-060)
javascript·大剑师·js面试题
Struggler2811 小时前
让ai更加精准的理解你的提示词
前端