栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么JSX道具不应该使用箭头功能或绑定?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么JSX道具不应该使用箭头功能或绑定?

为什么您不应该在JSX props中使用内联箭头功能

在JSX中使用箭头函数或绑定是不利于性能的不良做法,因为该函数会在每个渲染器上重新创建。

  1. 每当创建一个函数时,就会对前一个函数进行垃圾回收。渲染许多元素可能会在动画中产生垃圾。

  2. 使用内联箭头功能将导致

    PureComponent
    s和
    shallowCompare
    shouldComponentUpdate
    方法中使用的组件重新渲染。由于箭头函数prop每次都会重新创建,因此浅表比较会将其标识为对prop的更改,并且组件将重新呈现。

在下面的两个示例中可以看到-当我们使用嵌入式箭头功能时,

<Button>
每次都会重新渲染组件(控制台显示“渲染按钮”文本)。

示例1- 不带 内联处理程序的PureComponent

class Button extends React.PureComponent {  render() {    const { onClick } = this.props;    console.log('render button');    return (      <button onClick={ onClick }>Click</button>    );  }}class Parent extends React.Component {  state = {    counter: 0  }  onClick = () => this.setState((prevState) => ({    counter: prevState.counter + 1  }));  render() {    const { counter } = this.state;    return (      <div>        <Button onClick={ this.onClick } />        <div>{ counter }</div>      </div>    );  }}ReactDOM.render(  <Parent />,  document.getElementById('root'));<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script><div id="root"></div>

示例2- 具有 内联处理程序的PureComponent

class Button extends React.PureComponent {  render() {    const { onClick } = this.props;    console.log('render button');    return (      <button onClick={ onClick }>Click</button>    );  }}class Parent extends React.Component {  state = {    counter: 0  }  render() {    const { counter } = this.state;    return (      <div>        <Button onClick={ () => this.setState((prevState) => ({          counter: prevState.counter + 1        })) } />        <div>{ counter }</div>      </div>    );  }}ReactDOM.render(  <Parent />,  document.getElementById('root'));<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script><div id="root"></div>

this
不带内联箭头功能的绑定方法

  1. 在构造函数中手动绑定方法:

    class Button extends React.Component {

    constructor(props, context) {
    super(props, context);

    this.cb = this.cb.bind(this);

    }

    cb() {

    }

    render() {
    return (

    );
    }
    }

  2. 使用带有箭头功能的proposal-class-fields绑定方法。由于这是第3阶段的建议,因此您需要添加第3阶段的预设或将Class属性转换为babel配置。

    class Button extends React.Component {

    cb = () => { // the class property is initialized with an arrow function that binds this to the class

    }

    render() {
    return (

    );
    }
    }

具有内部回调的功能组件

当我们在函数组件内部创建内部函数(例如事件处理程序)时,每次渲染组件时都会重新创建该函数。如果将函数作为道具(或通过上下文)传递给子组件(

Button
在这种情况下),则该子组件也会重新渲染。

示例1-具有内部回调的功能组件:

const { memo, useState } = React;const Button = memo(({ onClick }) => console.log('render button') || (  <button onClick={onClick}>Click</button>));const Parent = () => {  const [counter, setCounter] = useState(0);  const increment = () => setCounter(counter => counter + 1); // the function is recreated all the time  return (    <div>      <Button onClick={increment} />      <div>{counter}</div>    </div>  );}ReactDOM.render(  <Parent />,  document.getElementById('root'));<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>

为了解决这个问题,我们可以使用

useCallback()
hook来包装回调,并将依赖项设置为一个空数组。

注意:

useState
生成函数接受更新器功能,其提供当前状态。这样,我们无需将当前状态设置为的依赖项
useCallback

示例2-具有内部回调的函数组件,该内部回调包装有useCallback:

const { memo, useState, useCallback } = React;const Button = memo(({ onClick }) => console.log('render button') || (  <button onClick={onClick}>Click</button>));const Parent = () => {  const [counter, setCounter] = useState(0);  const increment = useCallback(() => setCounter(counter => counter + 1), []);  return (    <div>      <Button onClick={increment} />      <div>{counter}</div>    </div>  );}ReactDOM.render(  <Parent />,  document.getElementById('root'));<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>


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/517813.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号