资讯专栏INFORMATION COLUMN

02.react进阶指南

zzbo / 443人阅读

摘要:指定读取当前的。它为其后代元素触发额外的检查和警告。严格模式检查仅在开发模式下运行它们不会影响生产构建。作用识别不安全的生命周期关于使用过时字符串的警告关于使用废弃的方法的警告检测意外的副作用检测过时的为高阶组件。

react 进阶 懒加载

React.lazy函数能让你像渲染常规组件一样处理动态引入(的组件)。
Suspense加载指示器为组件做优雅降级。
fallback属性接受任何在组件加载过程中你想展示的 React 元素。

const OtherComponent = React.lazy(() => import("./OtherComponent"));

function MyComponent() {
  return (
    
Loading...
}>
); } Context

Context提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法,设计目的是为了共享那些对于一个组件树而言是“全局”的数据。

// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext("light");

class App extends React.Component {
  render() {
    // 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
    // 无论多深,任何组件都能读取这个值。
    // 在这个例子中,我们将 “dark” 作为当前的值传递下去。
    return (
      
        
      
    );
  }
}

// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar(props) {
  return (
    
); } class ThemedButton extends React.Component { // 指定 contextType 读取当前的 theme context。 // React 会往上找到最近的 theme Provider,然后使用它的值。 // 在这个例子中,当前的 theme 值为 “dark”。 static contextType = ThemeContext; render() { return

请谨慎使用,因为这会使得组件的复用性变差。

API:

React.createContext
创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。

Context.Provider
每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。

Class.contextType
挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。这能让你使用 this.context 来消费最近 Context 上的那个值。你可以在任何生命周期中访问到它,包括 render 函数中。

Context.Consumer
这里,React 组件也可以订阅到 context 变更。这能让你在函数式组件中完成订阅 context。

Refs

Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。不能在函数组件上使用 ref 属性,因为他们没有实例,可以在函数组件内部使用 ref 属性。

适合使用 refs 的情况:

管理焦点,文本选择或媒体播放。

触发强制动画。

集成第三方 DOM 库。

使用方法:

创建 Refs

Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return 
; } }

访问 Refs

在 ref 的 current 属性中被访问

const node = this.myRef.current;
Refs 转发

Ref 转发是一项将 ref 自动地通过组件传递到其一子组件的技巧。子组件使用React.forwardRef接收ref。可用于Hoc处理ref。

const FancyButton = React.forwardRef((props, ref) => (
  
));

// 你可以直接获取 DOM button 的 ref:
const ref = React.createRef();
Click me!;

上例中,FancyButton 使用 React.forwardRef 来获取传递给它的 ref,然后转发到它渲染的 DOM button。这样,使用 FancyButton 的组件可以获取底层 DOM 节点 buttonref ,并在必要时访问,就像其直接使用 DOM button 一样。

Fragments

Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。key 是唯一可以传递给 Fragment 的属性

render() {
  return (
    
      
      
      
    
  );
}

可简写为<>

高阶组件(HOC)

HOC是参数为组件,返回值为新组件的函数。

HOC 不会修改传入的组件,也不会使用继承来复制其行为。相反,HOC 通过将组件包装在容器组件中来组成新组件。HOC 是纯函数,没有副作用。

示例:

// 此函数接收一个组件...
function withSubscription(WrappedComponent, selectData) {
  // ...并返回另一个组件...
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.handleChange = this.handleChange.bind(this);
      this.state = {
        data: selectData(DataSource, props)
      };
    }

    componentDidMount() {
      // ...负责订阅相关的操作...
      DataSource.addChangeListener(this.handleChange);
    }

    componentWillUnmount() {
      DataSource.removeChangeListener(this.handleChange);
    }

    handleChange() {
      this.setState({
        data: selectData(DataSource, this.props)
      });
    }

    render() {
      // ... 并使用新数据渲染被包装的组件!
      // 请注意,我们可能还会传递其他属性
      return ;
    }
  };
}

上例中class组件为HOC的容器组件,容器组件担任分离将高层和低层关注的责任,由容器管理订阅和状态,并将 prop 传递给处理渲染 UI。HOC 使用容器作为其实现的一部分,你可以将 HOC 视为参数化容器组件。

注意事项:

不要在 render 方法中使用 HOC。

在render中使用会导致diff 算法在对比组件变化时每次检测都不一样,每次渲染都会进行卸载,和重新挂载的操作,这不仅仅是性能问题 - 重新挂载组件会导致该组件及其所有子组件的状态丢失。

务必复制静态方法到容器组件上。

可以使用hoist-non-react-statics自动拷贝所有非 React 静态方法

import hoistNonReactStatic from "hoist-non-react-statics";
function enhance(WrappedComponent) {
  class Enhance extends React.Component {/*...*/}
  hoistNonReactStatic(Enhance, WrappedComponent);
  return Enhance;
}

Refs 不会被传递。

可用过Refs 转发解决

常见的HOC:

redux的 connect

React.PureComponent

大部分情况下,你可以使用 React.PureComponent 来代替手写 shouldComponentUpdate。只有当检测数据是数组或对象时,由于浅拷贝的问题会导致比较出现偏差不能使用,此时使用深拷贝仍可继续使用。

如以下代码:

class CounterButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false;
  }

  render() {
    return (
      
    );
  }
}

可替换为:

class CounterButton extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  render() {
    return (
      
    );
  }
}
Portals

Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。

一个 portal 的典型用例是当父组件有 overflow: hidden 或 z-index 样式时,但你需要子组件能够在视觉上“跳出”其容器。例如,对话框、悬浮卡以及提示框:

render() {
  // React 并*没有*创建一个新的 div。它只是把子元素渲染到 `domNode` 中。
  // `domNode` 是一个可以在任何位置的有效 DOM 节点。
  return ReactDOM.createPortal(
    this.props.children,
    domNode
  );
}
React.StrictMode

StrictMode 不会渲染任何可见的 UI。它为其后代元素触发额外的检查和警告。严格模式检查仅在开发模式下运行;它们不会影响生产构建。

作用:

识别不安全的生命周期

关于使用过时字符串 ref API 的警告

关于使用废弃的 findDOMNode 方法的警告

检测意外的副作用

检测过时的 context API

React.memo

React.memo 为高阶组件。它与 React.PureComponent 非常相似,但它适用于函数组件,但不适用于 class 组件。

如果你的函数组件在给定相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React 将跳过渲染组件的操作并直接复用最近一次渲染的结果。

默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。

const MyComponent = React.memo(function MyComponent(props) {
  /* 使用 props 渲染 */
});
原文git地址 觉得有用的话,来个star鼓励,持续更新中。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106564.html

相关文章

  • web前端工程师进阶指南

    摘要:进阶的知识的话就是响应式这一块了,一套代码能适配手机是初级前端工程师的进阶,在北京工资一般在左右。进阶的知识应该是这一块了,当然并不难,了解怎么与后台交互是学习的关键点,在北京的工资一般在左右。 web前端?如果你是一名web前端工程师,那么你将感到幸运,从之前的默默无闻,到后来的给后台工程师打下手,再到巅峰一时。web前端可谓是当下最火的职位之一。 showImg(https://s...

    曹金海 评论0 收藏0
  • web前端工程师进阶指南

    摘要:进阶的知识的话就是响应式这一块了,一套代码能适配手机是初级前端工程师的进阶,在北京工资一般在左右。进阶的知识应该是这一块了,当然并不难,了解怎么与后台交互是学习的关键点,在北京的工资一般在左右。 web前端?如果你是一名web前端工程师,那么你将感到幸运,从之前的默默无闻,到后来的给后台工程师打下手,再到巅峰一时。web前端可谓是当下最火的职位之一。 showImg(https://s...

    fnngj 评论0 收藏0
  • 【GPU云主机 UHost】产品简介、产品优势、机型与性能和深度学习指南

    摘要:云主机产品简介增强型云主机是基于成熟的云计算技术,专享高性能硬件的云主机服务。目前提供采用采用和采用机型。支持多种操作系统增强型云主机支持多种操作系统,如等,以适应不同行业的专业软件及建模需求。机型与性能型可选颗。GPU云主机UHost产品简介GPU增强型云主机是基于UCloud成熟的云计算技术,专享高性能GPU硬件的云主机服务。大幅提升图形图像处理和高性能计算能力,并具备弹性、低成本、易于...

    Tecode 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0

发表评论

0条评论

zzbo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<