【问题标题】:Is there any difference between rendering a functional component with and without hooks?渲染带有和不带有钩子的功能组件有什么区别吗?
【发布时间】:2019-04-04 23:18:29
【问题描述】:

刚刚尝试了一些 react-hooks 并得到了一些问题。

考虑这个带有 react-hooks 的功能组件:

const Counter = (props) => {
  console.log("Counter component");

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

  const handleIncrease = () => {
    setCount(count + 1);
  }

  const handleDecrease = () => {
    setCount(count - 1);
  }

  return (
    <div>
      <button onClick={handleIncrease}>+</button>
      <button onClick={handleDecrease}>-</button>
      <p>{count}</p>
    </div>
  )
}

每次点击“+”或“-”都会记录。

这是否意味着这个组件(或者说,函数)中的每个处理程序都被重新声明并重新分配给一个变量?如果是这样,会不会导致一些性能问题?

对我来说,带有钩子的函数式组件似乎是经典组件的巨大渲染方法,如下所示:

class Counter extends React.Component {
  state = {
    count: 0,
  }

  render() {
    const handleIncrease = () => {
      this.setState({ count: this.state.count + 1 });
    }

    const handleDecrease = () => {
      this.setState({ count: this.state.count - 1 });
    }

    return (
      <div>
        <button onClick={handleIncrease}>+</button>
        <button onClick={handleDecrease}>-</button>
        <p>{count}</p>
      </div>
    )
  }
}

我认为没有人会这样做。

我是否对 React 的渲染机制有误解,或者在使用带有 react-hooks 的功能组件时它不是最佳实践?

【问题讨论】:

  • 当一个 prop 或 state 改变时,整个函数会再次重新运行,正如你所怀疑的那样。
  • 啊..谢谢!我确实错过了 useCallback 和 useMemo。但是,尽管它防止了子组件不必要的重新渲染,React 仍然在每次重新渲染功能组件时执行“useCallback(...)”钩子,对吧?不知道是不是会造成一些性能问题,还是和使用经典组件的成本相比算不了什么?

标签: reactjs react-hooks


【解决方案1】:

虽然在函数式组件中,函数会在每次渲染时重新创建,但与收益相比,它的性能成本要低得多。

您可以参考这篇文章了解更多详情:Performance penalty of creating handlers on every render

但是您仍然可以进行优化,以便不会在每次使用 useCallbackuseReducer(depending on whether your updates are complex or not) 时重新创建函数

const Counter = (props) => {
  console.log("Counter component");

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

  const handleIncrease = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, [])

  const handleDecrease = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, [])

  return (
    <div>
      <button onClick={handleIncrease}>+</button>
      <button onClick={handleDecrease}>-</button>
      <p>{count}</p>
    </div>
  )
}

在上面的示例中,函数仅在初始渲染时重新创建,使用状态更新回调我们可以更新状态并避免关闭问题

【讨论】:

  • 非常感谢!那篇文章完全回答了我的问题。
  • 很高兴能帮上忙 :-)
猜你喜欢
  • 1970-01-01
  • 2020-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2012-06-20
相关资源
最近更新 更多