导入 react 的正确方法

简介: ## 背景 目前我们常见的有两种引入 `react` 的方法: ```js import React from 'react'; // vs import * as React from 'react'; ``` 这两种写法目前都可以运行,但是同一个目的出现两种写法就容易产生分歧,本文主要阐述这两种写法的不同并给出我建议的写法。 ## 便捷性 从便捷性角度来讲

背景

目前我们常见的有两种引入 react 的方法:

import React from 'react';
// vs
import * as React from 'react';

这两种写法目前都可以运行,但是同一个目的出现两种写法就容易产生分歧,本文主要阐述这两种写法的不同并给出我建议的写法。

便捷性

从便捷性角度来讲,无疑第一种方式要少打好多字符。另外如果我们要引用 react 包内的其它导出项时,第一种方式的有点更明显:

import React, { useState } from 'react';

export default function MyComponent() {
  const [foo, setFoo] = useState();

  return <div>{foo}</div>;
}

对比后一种写法:

import * as React from 'react';

export default function MyComponent() {
  const [foo, setFoo] = React.useState();

  return <div>{foo}</div>;
}

这里只能通过 React 命名空间来引用内部导出项。

或者也可以单独再导出一遍内部项:

import * as React from 'react';
import { useState } from 'react';

无论怎么写,都很难达到第一种写法的便捷性。

语法和语义

ES 语法里并没有命名空间的语法,export 关键字是作用于当前文件的,因此只有文件是在 ES Module 语义下的命名空间。

export default 只是 export 的一个特例,用于导出一个特殊的名字,并不能用来导出一个命名空间.有人还是习惯于用一个对象来模拟一个命名空间:

export default {foo, bar};

这种写法并不符合 ES Module 的方式,构建工具是无法进行静态分析,也无法进行 Tree Shaking

更多关于 export default 的解释可以参考 《export default 真的有害吗?》

从语义的角度来讲,第一种写法就是错误的,React 仅仅是作为一个命名空间存在的,我们并不会像使用一个值一样来使用 React。从 React 16.13.0 开始,React 的导出方式也已经更正为 export {xxx, ...} 的形式了(commit)。

之所以第一种导入方式还可以使用,是因为目前 React 的构建产物是 Commonjs 规范的,webpack 等构建工具做了兼容。

自动导入

相对于语义的正确性,我觉得这一点便捷性是应该牺牲一下的,但是有没有在不牺牲语义的情况下获得便捷的方法?下面我们来聊聊自动导入。

正常情况,我们不需要使用 import * as 语法来导入一个包,但是 JSX 文件的编译需要 React 命名空间。既然 JSX 是语法层面的扩展,那么把这个命名空间的导入也放到语法层面去解决也是理所当然的。

babel-plugin-transform-react-jsx 的自动导入模式目前只在 React 17 中可用,针对之前的版本,我们可以使用非官方的 babel-plugin-auto-import 插件。

总结

如何导出决定如何导入。

按顺序简要列一下可选的导入方案:

  1. 【最佳方案】自动导入
  2. 【兼容性好】import * as React from 'react';
  3. 【不再推荐】import React from 'react';

思考题

下面两种导入样式的写法有什么区别?应该选择哪种?

  • import * as styles from './index.module.scss
  • import styles from './index.module.scss

提示:https://webpack.js.org/loaders/style-loader/#esmodule

相关文章
|
2月前
|
前端开发
|
2月前
|
Android开发
jmessage-react-plugin的正确引入方法
jmessage-react-plugin的正确引入方法
15 1
|
3月前
|
前端开发 JavaScript 开发者
请详细介绍React挂载阶段的方法。
请详细介绍React挂载阶段的方法。
61 9
|
4月前
|
前端开发 JavaScript
React 组件生命周期方法详解
【8月更文挑战第30天】
55 5
|
3月前
封装react-antd-table组件参数以及方法如rowSelection、pageNum、pageSize、分页方法等等
文章介绍了如何封装React-Antd的Table组件,包括参数和方法,如行选择(rowSelection)、页码(pageNum)、页面大小(pageSize)、分页方法等,以简化在不同表格组件中的重复代码。
74 0
|
4月前
|
前端开发 JavaScript API
学习 React 的方法
【8月更文挑战第26天】学习 React 的方法
39 1
|
4月前
|
前端开发 JavaScript 开发者
React生命周期方法完全指南:深入理解并高效应用每个阶段的钩子——从初始化到卸载的全方位解析
【8月更文挑战第31天】本文详细介绍了React组件生命周期方法,包括初始化、挂载、更新和卸载四个阶段的关键钩子。通过探讨每个阶段的方法,如`componentDidMount`和`componentWillUnmount`,帮助开发者在正确时机执行所需操作,提升应用性能。文章还提供了最佳实践,指导如何避免常见错误并充分利用最新钩子。
107 0
|
4月前
|
前端开发 JavaScript 开发者
React 中的生命周期方法是什么?
【8月更文挑战第31天】
55 0
|
5月前
|
前端开发 Scala
Scala并发编程的react、loop方法详解
在这个例子中,`MyActor`会无限循环接收和处理消息。当收到一个字符串消息时,它会打印出"Received: "加上消息内容。如果收到其他类型的消息,它会打印"Unknown message"。
29 1
|
7月前
|
前端开发 JavaScript 开发者
在React中,如何利用生命周期方法管理组件的状态和行为?
【5月更文挑战第29天】在React中,如何利用生命周期方法管理组件的状态和行为?
57 3