钩子不感兴趣的值导致重新渲染

时间:2019-12-21 21:38:55

标签: reactjs react-hooks

让我们说我创建了一个自定义挂钩,它将返回一些状态和一个函数,因此请修改该状态。

我将此挂钩与组件一起使用,只关心它返回的功能而不是状态。所以我从钩子上解构了函数。

当我调用此函数时,由于我正在使用该钩子(无论是否关心它的状态),它似乎会导致组件上的重新渲染,因为钩子将要更新。

我已经创建了此here

的示例

下面是代码的副本:

import React, { useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const useCount = () => {
  const [count, setCount] = useState(0);

  const changeCount = newCount => {
    setCount(newCount);
  };

  console.log("useCount: " + count);

  return {
    count,
    changeCount
  };
};

const App = () => {
  const { changeCount } = useCount();

  const handleOnClick = () => {
    const newCount = Math.floor(Math.random() * 10 + 1);
    console.log("new count: " + newCount);
    changeCount(newCount);
  };

  console.log("app render");

  return (
    <div>
      <button type="button" onClick={handleOnClick}>
        Click Me Boi!
      </button>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

当您单击按钮时,它会导致App组件重新呈现,这是因为我认为是因为该钩子的状态将要更新,即使您并未从钩子中检索该状态,您仍然依赖钩子。

所以我的问题是正确的吗?如果可以,是否有一种方法可以停止我的应用程序组件的重新渲染(如果它不/不关心状态,仅关心功能)?

渲染是否不可避免,因为如果我确实调用了该函数,由于该函数实际上已更改,因为它本身依赖于将要更新的setCount,因此它仍需要更新吗?

任何帮助将不胜感激:)

1 个答案:

答案 0 :(得分:1)

通过useState()更新程序设置状态会导致重新渲染。如果要缓存当前值,但又不想引起重新渲染,则将该值分配给ref:

const { useRef } = React;

const useCount = () => {
  const count = useRef(0);

  const changeCount = newCount => {
    count.current = newCount;
    console.log("useCount: " + count.current);
  };

  return [
    changeCount
  ];
};

const App = () => {
  const [changeCount] = useCount();

  const handleOnClick = () => {
    const newCount = Math.floor(Math.random() * 10 + 1);
    console.log("new count: " + newCount);
    changeCount(newCount);
  };

  console.log("app render");

  return (
    <div>
      <button type="button" onClick={handleOnClick}>
        Click Me Boi!
      </button>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>