如何测试 React 组件 props 改变的场景

阅读时长 8 分钟读完

在 React 开发中,组件的 props 是非常重要的概念,很多场景下需要测试当 props 改变时组件的行为。本篇文章将介绍一些测试 React 组件 props 改变的场景及其解决方案。

场景一:组件接收 props,进行更新

在 React 组件中,我们通常会将父组件传递的 props 保存在组件的 state 中,然后在组件的 render 方法中根据 state 渲染组件。当父组件修改传递给子组件的 props 的值时,子组件的 state 也需要更新,以触发重新渲染。

假设我们有一个 Counter 组件,需要接收一个初始计数值,然后可以被增加或减少。我们可以将组件的 state 初始化为 props 传入的计数值,然后在操作按钮点击时更新 state,最后渲染更新后的计数值。

-- -------------------- ---- -------
------ ------ - -------- - ---- --------

-------- --------- ------------ -- -
  ----- ------- --------- - -----------------------

  ----- --------------- - -- -- -------------- - ---
  ----- --------------- - -- -- -------------- - ---

  ------ -
    -----
      --------- -----------
      ------- ------------------------------------
      ------- ------------------------------------
    ------
  --
-

现在我们需要测试当 initialValue 改变时,组件能否正确地重新渲染计数值。我们可以使用 react-testing-library 提供的 render 和 fireEvent 方法来实现。

-- -------------------- ---- -------
------ ----- ---- --------
------ - ------- --------- - ---- -------------------------
------ ------- ---- ------------

------------- --- ------- ---- ------- ----- ----------- -- -- -
  ----- - --------- - - --------------- ---------------- ----
  ------------------------ -------------------------
---

------------- --- ------- ------- ----------- -- -- -
  ----- - ---------- -------- - - --------------- ---------------- ----
  --------------------------------
  ----------------- ---------------- ----
  ------------------------ -------------------------
---

在第一个测试中,我们首先渲染了带有初始值的 Counter 组件,然后使用 getByText 方法来获取计数器元素,并使用 toBeInTheDocument 方法来断言该元素是否在文档中。在第二个测试中,我们首先渲染了带有初始值的 Counter 组件,然后模拟了点击操作按钮,并使用 rerender 方法重新渲染组件并传入新的初始值。最后,我们再次使用 getByText 方法来获取计数器元素,并断言元素是否已被更新为新的计数值。

场景二:组件接收 props,不会更新 state

在某些情况下,组件只需要在初始化时读取 props 的值,不需要根据 props 更新 state。比如一个显示用户信息的组件,用户信息只需要在组件初始化时读取一次,而不需要每次 props 变化都重新更新组件。

我们可以使用 useEffect 钩子来实现该场景。在 useEffect 中,我们可以监听 props 的变化,并在变化时执行一些操作。在组件初始化时,我们需要将 props 的值设置为组件 state 的初值,并在 useEffect 中监听 props 的变化,当 props 变化时不再更新 state,而是执行我们需要的操作。

假设我们有一个 User 组件,需要接收一个用户 id,然后根据 id 查询用户信息。我们可以将组件 state 初始化为 null,然后在组件挂载时查询用户信息,并将查询结果保存在 state 中,最后渲染用户信息。

-- -------------------- ---- -------
------ ------ - --------- --------- - ---- --------

-------- ------ ------ -- -
  ----- ------ -------- - ---------------

  ------------ -- -
    -- ---- --- -- --- ---- ---- ----- -- ---- --
    -----------------------------------------------
      -------------- -- ----------------
      ---------- -- ---------------
  -- ----------

  -- ------- -
    ------ ----------------------
  -

  ------ -
    -----
      -------- ---------------
      --------- ----------------
    ------
  --
-

现在我们需要测试当 userId 改变时,组件能否正确地重新渲染用户信息。我们可以使用 react-testing-library 提供的 render 方法和 wait 方法来实现。

-- -------------------- ---- -------
------ ----- ---- --------
------ - ------- ---- - ---- -------------------------
------ ---- ---- ---------

----------------------- -- --
  ---------- --
    -----------------
      ----- -- -- ----------------- ----- -------- ------ ------------------- --
    --
  -
--

------------- --- ---- ---- ---- ------- ----- ----------- ----- -- -- -
  ----- - --------- - - ------------ ---------- ----
  ----------------------------------------------------
  ----- ------- -- ----------------------- ------------------------------
  ------------------------ -----------------------------------------
---

------------- --- ------- ---- ---- ----------- ----- -- -- -
  ----- - ---------- -------- - - ------------ ---------- ----
  --------------------- -- ----- ---- ----- ------
  ----- ------- -- ----------------------- ------------------------------

  --------------------------- --
    -----------------
      ----- -- -- ----------------- ----- ------ ------ ----------------- --
    --
  --
  -------------- ---------- ----

  ----------------------------------------------------
  ----- ------- -- ----------------------- ----------------------------
  ------------------------ ---------------------------------------
---

在第一个测试中,我们首先渲染了带有初始 userId 的 User 组件,然后使用 getByText 方法来获取 Loading... 元素,并使用 toBeInTheDocument 方法来断言该元素是否在文档中。随后,我们使用 wait 方法等待异步操作完成,然后再次使用 getByText 方法来获取用户信息元素,并断言元素是否已被更新为新的用户信息。在第二个测试中,我们首先渲染了带有初始 userId 的 User 组件,然后在监听完第一次组件渲染的异步请求后,使用 jest.clearAllMocks 方法来重置 fetch 方法的 mock。接着,我们 mock 了新的异步请求,然后重新渲染组件并传入新的 userId。最后,我们使用和第一个测试类似的方法获取新的用户信息,并断言元素是否已被更新为新的用户信息。

总结一下,测试 React 组件 props 改变的场景,需要使用 react-testing-library 提供的 render 方法和 fireEvent 方法或者 wait 方法,以模拟组件挂载和渲染过程,并使用 expect 方法断言组件的行为是否正确。在某些场景下,我们需要使用 useEffect 钩子来对 props 的变化做出响应,并在 useEffect 函数中执行一些操作。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64730a42968c7c53b008ff03

纠错
反馈