The library for web and native user interfaces

React Escape Hatches

The library for web and native user interfaces
有些组件可能需要控制和同步 React 之外的系统。例如,你可能需要使用浏览器 API 聚焦输入框,或者在没有 React 的情况下实现视频播放器,或者连接并监听远程服务器的消息。

使用 ref 引用值 

当你希望组件“记住”某些信息,但又不想让这些信息 触发新的渲染 时,你可以使用 ref

const ref = useRef(0);

与 state 一样,ref 在重新渲染之间由 React 保留。但是,设置 state 会重新渲染组件,而更改 ref 不会!你可以通过 ref.current 属性访问该 ref 的当前值。

  function handleClick() {
    ref.current = ref.current + 1;
    alert('你点击了 ' + ref.current + ' 次!');
  }

使用 ref 操作 DOM 

由于 React 会自动更新 DOM 以匹配渲染输出,因此组件通常不需要操作 DOM。但是,有时可能需要访问由 React 管理的 DOM 元素——例如聚焦节点、滚动到此节点,以及测量它的尺寸和位置。React 没有内置的方法来执行此类操作,所以需要一个指向 DOM 节点的 ref 来实现。

const inputRef = useRef(null);

function handleClick() {
  inputRef.current.focus();
}

使用 Effect 实现同步

与处理特定事件的事件处理程序不同,Effect 在渲染后运行一些代码。使用它将组件与 React 之外的系统同步。

  useEffect(() => {
    console.log(isPlaying)
  }, [isPlaying]);

许多 Effect 也会自行“清理”。

  useEffect(() => {
    const connection = createConnection();
    connection.connect();
    return () => connection.disconnect();
  }, []);

你可能不需要 Effect

Effect 是 React 范式中的一种脱围机制。它们可以“逃出” React 并使组件和一些外部系统同步。如果没有涉及到外部系统(例如,需要根据一些 props 或 state 的变化来更新一个组件的 state),不应该使用 Effect。移除不必要的 Effect 可以让代码更容易理解,运行得更快,并且更少出错。

有两种常见的不必使用 Effect 的情况:

  • 不必为了渲染而使用 Effect 来转换数据。
  • 不必使用 Effect 来处理用户事件

响应式 Effect 的生命周期

Effect 的生命周期不同于组件。组件可以挂载、更新或卸载。Effect 只能做两件事:开始同步某些东西,然后停止同步它。如果 Effect 依赖于随时间变化的 props 和 state,这个循环可能会发生多次。

移除 Effect 依赖

不必要的依赖关系可能会导致 Effect 运行过于频繁,甚至产生无限循环。删除它们的方式取决于具体情况。

使用自定义 Hook 复用逻辑

React 有一些内置 Hook,例如 useStateuseContextuseEffect。为了实现效果,可以根据应用需求创建自己的 Hook。把 Effect 包裹进自定义 Hook 可以准确表达你的目标以及数据在里面是如何流动的。

Rick Zheng

Rick Zheng

Scientist working on creating NekoMusume
Shanghai