> For the complete documentation index, see [llms.txt](https://onenesss-organization.gitbook.io/jj-xiaoce/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://onenesss-organization.gitbook.io/jj-xiaoce/react-jin-jie-shi-jian-zhi-nan/42.-zong-jie-pian-ru-he-you-xiao-yue-du-yuan-ma.md).

# 42. 总结篇-如何有效阅读源码

### 前言

> 一流工程师天生充满了责任感和好奇心,他们大都满怀信心但却虚怀若谷，他们直接但不粗鲁，他们不推诿，他们不在乎工作边界，以团队任务而不是自己的工作任务为模板。我不止一次领教过一流工程师的威力，他们不止能把事情做对，还能把事情做好。他们能在完成开发的同时还能把团队不必要的沟通、返工和流程成本降到最低，更能防患于未然，把各种凶险消弭于无形。 --《浪潮之巅》：吴军博士讲述硅谷IT发展史

在目前读者的反馈中，说到小册里面的源码部分看起来比较头疼，很难理解。实际我在小册中放了一些源码主要为了让大家了解 React 中一些核心细节和主要流程。只有知道这些，才能更熟练的运用 React ，才能更好地解决工作中一些复杂的场景问题。接下来我把我阅读源码的心得分享给大家，希望能对大家有帮助。

### 如何高效阅读源码（彩蛋）

在阅读源码过程中，我遵循这几个技巧，感觉很有效果。

#### 1 知己知彼

首先在阅读源码之前，第一步就是要明白看的是什么？ 是否熟悉里面的 api？ 是否在真实的项目中使用过？ 如果对于同一个库，工作中使用过的开发者看源码，要比没有使用过直接看源码，容易的多。

* 比如想看 `react-redux` 源码，就要先知道 react-redux 中 Provider 是做什么的 ？ `connect` 怎么使用的，它有几个参数，每个参数有什么意义？
* 比如想看 `mobx-react` 源码，就要先知道 mobx-react 中 `inject` ，`observer` 的作用。

开发者对一个库或者一个框架越熟悉，看源码也就越容易，甚至如果真的精通一个框架本身，那么很有可能不看源码就猜到框架内部是如何实现的，正所谓庖丁解牛。

#### 2 渐进式｜分片式阅读

看源码千万不要想着**一口气吃成个胖子**，作者看 React 源码，陆陆续续看了一年，当然不是天天都在看，但是中间也没有间隔太久，如果想要快速看完源码，懂得原理，那么**只能从看源码到放弃**。

作者看源码遵循 **渐进式 ，分片式** 原则。

* 渐进式： 拿 React 为例子🌰，如果一上来就看 React 核心调和调度流程，那么一下就会蒙，就会找不到头绪，看着看着就会变成看天书，所以可以先看一下基础的，比如 fiber 类型，React 如何创建 fiber ，每个 fiber 属性有什么意义。然后再慢慢渗透核心模块，这样效果甚佳。
* 分片式：对于一个框架的源码学习，要制定计划，化整为零，每天学习一点点，每一次学习都做好笔记，两次学习的间隔最好不要太长时间。

#### 3 带着问题，带着思考去阅读

带着问题学习源码是最佳的学习方案，而且作者可以保证，这种方式每一次看都会有收获。即使很多开发者看源码坚持不下去，就是因为没有带着问题，没有去思考。

如果没有问题的去看源码，看着看着就会变得盲目，而且很有可能犯困。这样是坚持不下去的。

那么如何带着问题去思考呢？ 作者这里举了个例子🌰，比如现在想看 React Hooks 源码。那么我写一段 React Hooks 代码片段，看一下可以从中汇总出哪些问题？

```js
import React , { useContext , useState , useRef, useEffect, useLayoutEffect, useMemo } from 'react'
const newContext = React.createContext(null)
/* ① React Hooks 必须在函数组件内部执行？，React 如何能够监听 React Hooks 在外部执行并抛出异常。  */
const value = useContext(newContext)
console.log(value)
function Index(props){
    const [ number, setNumber ] = useState(0)
    // ②  React Hooks 如何把状态保存起来？保存的信息存在了哪里？
    let number1 , setNumber1
    // ③ React Hooks 为什么不能写在条件语句中？
    if(props.isShow) [ number1 , setNumber1 ] = useState(0)
    const cacheState = useRef(0)
    const trueValue = useMemo(()=>{
        // ④ useMemo 内部引用 useRef 为什么不需要添加依赖项，而 useState 就要添加依赖项
        return number1 + number + cacheState.current
    },[ number ,number1 ])
    // ⑤ useEffect 添加依赖项 props.a ，为什么 props.a 改变，useEffect 回调重新执行。
    useEffect(()=>{
        console.log(1)
    },[ props.a ])
    // ⑥ React 如何区别 useEffect 和 useLayoutEffect ，执行时机有什么不同？
    useLayoutEffect(()=>{
        console.log(2)
    },[])

    return <div>《React 进阶实践指南》</div>
}
```

从上面的一段代码中，可以提炼出的问题有：

* ① React Hooks 为什么必须在函数组件内部执行？React 如何能够监听 React Hooks 在外部执行并抛出异常。
* ② React Hooks 如何把状态保存起来？保存的信息存在了哪里？
* ③ React Hooks 为什么不能写在条件语句中？
* ④ useMemo 内部引用 useRef 为什么不需要添加依赖项，而 useState 就要添加依赖项。
* ⑤ useEffect 添加依赖项 props.a ，为什么 props.a 改变，useEffect 回调函数 create 重新执行。
* ⑥ React 内部如何区别 useEffect 和 useLayoutEffect ，执行时机有什么不同？

如果带着以上问题去阅读源码，相信阅读之后肯定会有收获。这种带着问题去阅读好处是：

* **能够从源码中找到问题所在，更一针见血的了解原理**。
* **能让阅读源码的过程变得不是那么枯燥无味，能够更加坚定阅读**。

### 披荆斩棘 ，勇往直前！

这本小册作者从 2020 年就开始整理，2021 年四月初开始正式写，写了正好四个月。 四个月里作者拒绝一切社交活动，没有一个周末休息过，把 React 知识点，从点到线再到面的串联起来，展现给大家，可能写的比较仓促，有一些错别字，如果给大家阅读带来不便，还请大家见谅，我会一直维护这本小册，修复错别字和不正确的地方，对小册的内容做技术翻新，对小册内容做补充，特别是持续维护的章节（第十四章，第二十六章，第二十七章）。

**“路漫漫其修远兮，吾将上下而求索”** ，希望阅读到这里的每一个读者，不要把掌握小册的知识点作为学习 React 的终点，而是要当成学习的起点，带着对 React 全新的认识去使用，平时工作中要多敲多练，多学习一些 React 设计模式，多写一些自定义 Hooks 。在 React 技术成长之路上披荆斩棘 ，勇往直前！

最后的最后感谢大家支持我，认可我，祝福大家早日进阶 React 技术栈，在成长的道路上我与你们同行。🙏🙏🙏

如果在阅读过程中有什么问题欢迎大家加我微信，交个朋友，微信：**TH0000666**，也可以关注笔者公众号 **前端Sharing**，持续分享前端硬核文章～

![11118.jpg](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1fe8d3fa5d1440e4af905bb810f29b68~tplv-k3u1fbpfcp-watermark.image)
