在React中,如何处理事件?

在 React 中处理事件与在 DOM 元素上处理事件类似,但有一些语法和行为上的差异。以下是 React 事件处理的核心知识点和示例:

一、基本事件绑定

1. 内联函数
function Button() {
  return (
    <button onClick={(e) => {
      e.preventDefault(); // 阻止默认行为
      console.log('Button clicked');
    }}>
      Click me
    </button>
  );
}
2. 外部函数
function Button() {
  const handleClick = (e) => {
    console.log('Button clicked', e.target);
  };

  return <button onClick={handleClick}>Click me</button>;
}

二、事件对象

React 事件是合成事件(SyntheticEvent),与原生 DOM 事件类似,但有跨浏览器兼容性。

function Form() {
  const handleSubmit = (e) => {
    e.preventDefault(); // 阻止表单默认提交
    console.log('Form submitted');
  };

  return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}

三、传递参数

1. 箭头函数传递参数
function ListItem({ id, name }) {
  const handleDelete = () => {
    console.log('Deleting item:', id);
  };

  return <li onClick={handleDelete}>{name}</li>;
}
2. 绑定参数
function ListItem({ id, name }) {
  const handleDelete = (event) => {
    console.log('Deleting item:', id, event);
  };

  return <li onClick={handleDelete.bind(this, id)}>{name}</li>;
}

四、常见事件类型

1. 表单事件
function InputExample() {
  const [value, setValue] = useState('');

  const handleChange = (e) => {
    setValue(e.target.value);
  };

  return <input type="text" value={value} onChange={handleChange} />;
}
2. 键盘事件
function TextArea() {
  const handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      console.log('Enter pressed');
    }
  };

  return <textarea onKeyDown={handleKeyDown} />;
}
3. 焦点事件
function FocusExample() {
  const handleFocus = () => console.log('Input focused');
  const handleBlur = () => console.log('Input blurred');

  return <input onFocus={handleFocus} onBlur={handleBlur} />;
}
4. 鼠标事件
function HoverButton() {
  const handleMouseOver = () => console.log('Mouse over');
  const handleMouseOut = () => console.log('Mouse out');

  return (
    <button onMouseOver={handleMouseOver} onMouseOut={handleMouseOut}>
      Hover me
    </button>
  );
}

五、事件委托与冒泡

React 事件自动使用事件委托,所有事件都冒泡到顶层容器。

function Parent() {
  const handleClick = (e) => {
    console.log('Parent clicked');
    e.stopPropagation(); // 阻止事件冒泡
  };

  return (
    <div onClick={handleClick}>
      <Child />
    </div>
  );
}

function Child() {
  const handleClick = () => console.log('Child clicked');

  return <button onClick={handleClick}>Click me</button>;
}

六、受控与非受控组件事件

1. 受控组件
function Form() {
  const [name, setName] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Submitted name:', name);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <button type="submit">Submit</button>
    </form>
  );
}
2. 非受控组件
function Form() {
  const inputRef = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Submitted name:', inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

七、自定义事件

1. 组件间传递事件
function Parent() {
  const handleChildClick = (data) => {
    console.log('Received from child:', data);
  };

  return <Child onCustomEvent={handleChildClick} />;
}

function Child({ onCustomEvent }) {
  const handleClick = () => {
    onCustomEvent('Hello from child');
  };

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

八、事件处理的注意事项

事件命名使用驼峰命名法

// 正确
<button onClick={handleClick}>

// 错误(DOM 风格)
<button onclick={handleClick}>

不要直接调用事件处理函数

// 正确:传递函数引用
<button onClick={handleClick}>

// 错误:立即执行函数
<button onClick={handleClick()}>

在类组件中绑定 this

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this); // 绑定 this
  }

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

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

合成事件与原生事件

function NativeEventExample() {
  useEffect(() => {
    const handleScroll = () => {
      console.log('Window scrolled');
    };

    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll); // 清理事件
    };
  }, []);

  return <div>Scroll the window</div>;
}

九、事件处理性能优化

使用 useCallback 缓存回调

const handleClick = useCallback(() => {
  // 处理逻辑
}, [dependencies]);

避免内联函数导致的重新渲染

// 不好的做法(每次渲染都会创建新函数)
<button onClick={() => console.log('Clicked')}>

// 好的做法(使用预定义函数)
<button onClick={handleClick}>

十、事件处理的特殊场景

1. 处理文件上传
function FileUpload() {
  const handleFileChange = (e) => {
    const file = e.target.files[0];
    console.log('Selected file:', file);
  };

  return <input type="file" onChange={handleFileChange} />;
}
2. 阻止默认行为
function LinkExample() {
  const handleClick = (e) => {
    e.preventDefault(); // 阻止链接跳转
    console.log('Link clicked');
  };

  return <a href="#" onClick={handleClick}>Click me</a>;
}
3. 处理触摸事件
function TouchExample() {
  const handleTouchStart = (e) => {
    console.log('Touch started', e.touches);
  };

  return <div onTouchStart={handleTouchStart}>Touch me</div>;
}

通过以上方式,你可以在 React 中灵活处理各种事件,从简单的点击事件到复杂的自定义事件都能高效实现。

十一、学习资料

【方圆】网盘资料大全

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容