写在前面
本系列是博主在学习 React 过程中 阅读如下文档做出的笔记 如果有错误 希望在评论区指出哦 ??
预计将会更新如下内容
-
React 小册 – 扬帆起航
-
React 小册 – Hooks
-
React 小册 – CSS 解决方案
-
React 小册 – 生命周期
-
React 小册 – 状态管理 Redux
-
React 小册 – 状态管理 Redux 中间件
-
React 小册 – 状态管理 Mobx
-
React 小册 – Router
-
React 小册 – SSR
-
React 小册 – React 生态
本系列的所有代码你都可以在这个 ?仓库 中看到 –>
你可能需要知道的一丢丢 JS 语法
解构
const target = {
name: 'nanshu',
desc: {
height: 181,
age: 18,
},
};
// 解构第一层
const { name } = target;
// 解构第二层
const {
desc: { age },
} = target;
复制代码
展开运算符
展开运算符可以帮我们快速的浅拷贝一个可迭代的对象
例如我们要往一个对象中添加属性 或者覆盖属性时 我们不希望改变原来的对象 就可以使用这个
当然 展开运算符的使用场景 不仅于此 ?
const obj = { nickname: 'nanshu' };
const newObj = { ...obj, age: 18 };
复制代码
箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的 this ?
当我们需要返回一个对象时 可以用()包裹对象 从而省略 return
const setUsername = (username: string) => ({
type: 'SET_USER_NAME',
username,
});
复制代码
ESM
描述 | 语法 | 说明 |
---|---|---|
模块导出 | export xxx | |
默认导出 | export default xxx | 一个模块只能有一个默认导出 |
重新导出 | export * from xxx | 常作为聚合导出 统一管理模块入口 |
重命名导出 | export {xxx as xxx} from xxx | |
默认导入 | import xxx from xxx | 一个模块只能有一个默认导入 |
解构导入 | import {xxx} from xxx | |
重命名导入 | import {xxx as xxx} from xxx |
起步
在 html 中使用 React
在 html 使用 React 我们需要引入如下 script
-
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
-
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
- 将组件挂载到根节点上进行渲染
-
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
- 将 JSX 语法转换为 React.createElement
注意:在任何你使用到 JSX 语法的 script 内 加上 type=”text/babel” 否则它将不会生效
例如如下代码 你就可以在页面上看到 Hello React
<body>
<div id="root"></div>
<script
crossorigin
src="https://unpkg.com/react@17/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
const App = () => <h1>Hello React</h1>;
ReactDOM.render(<App />, document.getElementById('root'));
</script>
</body>
复制代码
JSX
JSX 语法本质
JSX 是 JS 的语法扩展 不能被浏览器直接执行 需要使用 babel 编译后 才可以在浏览器中正常执行
JSX 在 React 中用来描述用户界面 最终被 babel 编译为React.createElement(type,attrs,children)
-
type:用于标识节点的类型。它可以是类似“h1”“div”这样的标准 HTML 标签字符串,也可以是 React 组件类型或 React fragment 类型。
-
config:以对象形式传入,组件所有的属性都会以键值对的形式存储在 config 对象中。
-
children:以对象形式传入,它记录的是组件标签之间嵌套的内容,也就是所谓的“子节点”“子元素”。
所以 JSX 本质是只是一种语法糖 最终还是被转化为了React.createElement
我们可以在babel官网中 查看 JSX 最终被编译成了什么
<div class="header">
<div
class="title"
onClick={() => {
console.log('hello');
}}
>
Title
</div>
</div>;
// 经babel转换后
('use strict');
/*#__PURE__*/
React.createElement(
'div',
{
class: 'header',
},
/*#__PURE__*/ React.createElement(
'div',
{
class: 'title',
onClick: () => {
console.log('hello');
},
},
'Title'
)
);
复制代码
createElement 中并没有十分复杂的涉及算法或真实 DOM 的逻辑,它的每一个步骤几乎都是在格式化数据
也就是处理成我们耳熟能详的虚拟DOM
,关于虚拟DOM
我们都知道它解决了大量 DOM 操作带来的性能问题
但是 时至今日 浏览器的性能已经完成可以忽视这方面的消耗 虚拟DOM
在我看来更是一种一统大前端的野心
因为虚拟DOM
中包含着描述 UI 的信息 如果有一套规则可以将这些信息转换成每个平台支持的语言 那么 React 就可以屏蔽每个平台的差异 做到跨段开发
React 在早期的时候 react
和 react-dom
这两个包是在一起的 从 React15 开始 才开始分离 各司其职
这也是 RN 诞生的时候 这也可见一斑 react-dom
的作用
ReactDOM.render(
// 需要渲染的元素(ReactElement)
element,
// 元素挂载的目标容器(一个真实DOM)
container,
// 回调函数,可选参数,可以用来处理渲染结束后的逻辑
[callback]
);
复制代码
JSX 表达式
JSX 允许 在{}
中使用我们的 JS 表达式
在里面 我们可以使用变量 进行运算符的操作 调用方法 等等
<div>{new Date().toDateString()}</div>
复制代码
JSX 注释
JSX 有特殊的注释方法
{
/* 我是注释 这里是一个头部信息*/
}
<div className="header">我是头部</div>;
复制代码
特殊点
-
由于 JSX 是 JS 的语法扩展 但是在里面我们又可以书写类似 HTML 的东西 所以为了避免冲突
-
HTML 中 class 在 JS 中表示类 在 JSX 中 我们用className来代替
-
HTML 中 label 标签的 for 在 JS 中表示循环 在 JSX 中用htmlFor来代替
-
-
undefined / boolean / null
-
对于以上几种数据类型 JSX 不会将其渲染到页面上
-
利用这个特性 我们可以实现条件渲染
-
let flag = true
<div>{flag && "欢迎回来~~~"}</div>
复制代码
JSX 列表渲染
这一块主要使用到了数组的高阶函数 map
const _games = ['剑盾', '塞尔达', '马里奥制造', '风花雪月'];
const gamesUI = _games.map((item, index) => {
// ?♂️避免使用index作为唯一的key去使用 一般后端返回的数据都有唯一的key值
return <div key={index}>{item}</div>;
});
复制代码
JSX 事件绑定
例如 我们为如下的 dom 节点绑定一个点击事件
const handleClick = () => {
console.log('click...');
};
<button onClick={handleClick}>Click</button>;
复制代码
如果在类组件中 你可能就需要考虑到 this 的绑定问题了
使用 bind || 箭头函数 ???
开发规范
文件目录
内容 | 路径 | 说明 |
---|---|---|
存放静态资源,例如图片 | src/assets | 根据模块可以在 assets 下再新建文件夹 |
业务页面 | src/containers | 对应需求事实际页面 |
业务组件 | src/components | 业务公共组件,有些组件在封装的时候可以考虑后期的可扩展性,及通用性 |
页面路径 | src/routes | 页面路径 |
业务公共样式 | src/styles | 全局公共样式,可以在其他地方引用 |
实用公共函数 | src/utils | 例如网络请求 request,公共函数等 |
redux 状态 | src/store | 根据模块在划分文件 |
业务封装的钩子函数 | src/hooks | 与 components 思路类似,有些组件如果业务中多个地方在用,可以考虑后期抽离出来 |
服务端接口 | src/api | 存放所有的服务端接口 |
mock 数据 | src/mock | 存放一些 mock 数据 |