ReactDOM 是如何把组件渲染到 DOM 中的?

Create at 2017 09 2120 min read技术React

当我们在开发 React 项目中,第一次调用 ReactDOM.render 的时候都发生了什么呢? 今天就从源码角度来追踪一下这个问题(主要看流程, 而不纠结与细节)。

ReactDOMStackEntry

首先我们可以从 ReactDOM 的入口文件 ReactDOMStackEntry.js 中找到 render 方法。可以看到,render 方法是 ReactMount 组件提供的。

var ReactDOMStack = {
  findDOMNode: findDOMNode,
  render: ReactMount.render,
  unmountComponentAtNode: ReactMount.unmountComponentAtNode,
  version: ReactVersion,

  /* eslint-disable camelcase */
  unstable_batchedUpdat

React 源码浅析之 - onlyChildren

Create at 2017 09 212 min read技术ReactSourceCode

这个模块的代码非常简单,短短十几行。

var ReactElement = require("ReactElement")

var invariant = require("fbjs/lib/invariant")
function onlyChild(children) {
  invariant(
    ReactElement.isValidElement(children),
    "React.Children.only expected to receive a single React element child."
  )
  return children
}

module.exports = onlyChild

就是判断传入的 children 是不是一个合法的 React 元素,否则就抛错出来。判断的逻辑就在 ReactElement 模块里面:

ReactElement.isV

React 源码浅析之 - ReactElement

Create at 2017 09 216 min read技术ReactSourceCode

ReactElement

这个模块定义了 React 元素的行为和方法,首先看 ReactElement 函数:

ReactElement

var ReactElement = function (type, key, ref, self, source, owner, props) {
  var element = {
    // This tag allow us to uniquely identify this as a React Element
    $$typeof: REACT_ELEMENT_TYPE,

    // Built-in properties that belong on the element
    type: type,
    key: key,
    ref: ref,
    props: props,

    // Record the component responsible for creating this e

React 源码浅析之 - ReactChildren

Create at 2017 09 2111 min read技术ReactSourceCode

引入的模块

var ReactElement = require("ReactElement")

var emptyFunction = require("fbjs/lib/emptyFunction")
var invariant = require("fbjs/lib/invariant")

我们来看一下 ReactElement 模块,其他两个都是工具函数,不用关心。

Export 的对象

var ReactChildren = {
  forEach: forEachChildren,
  map: mapChildren,
  count: countChildren,
  toArray: toArray,
}

module.exports = ReactChildren

依次来看一下这个四个 API

forEach

React 源码浅析之 - ReactBaseClasses

Create at 2017 09 218 min read技术ReactSourceCode

引入的模块

var ReactNoopUpdateQueue = require("ReactNoopUpdateQueue")

var emptyObject = require("fbjs/lib/emptyObject")
var invariant = require("fbjs/lib/invariant")
var lowPriorityWarning = require("lowPriorityWarning")

其中, ReactNoopUpdateQueue 是默认的 updater ,用来提供 update, replaceState, setState 的入队操作,但可能是由于是默认 updater 的原因,只提供了 API 和对入参的校验,但没有提供实际的功能。比如:

Read more

React 源码浅析之 - 入口文件

Create at 2017 09 212 min read技术ReactSourceCode

本系列文章以 react 最新的版本: 16.0.0-beta.5 为准。 首先我们入口文件 ReactEntry.js 来看,

var ReactBaseClasses = require("ReactBaseClasses")
var ReactChildren = require("ReactChildren")
var ReactElement = require("ReactElement")
var ReactVersion = require("ReactVersion")

var onlyChild = require("onlyChild")

依赖模块: • ReactBaseClasses • ReactChildren • ReactElement • onlyChild • ReactElementValidator 接着:

var createElement = ReactElem

Redux 源码解读(长文慎入)

Create at 2017 08 1825 min read技术ReduxSourceCode

Redux 的源码非常的精炼,短短几百行代码,确提供了强大的功能。今天,我们就来一探究竟。

看源码最简单的方式,就是从入口文件来看,看它依赖哪些模块,然后在依次看这些模块的内容,最后也就对整个代码有个清晰的认识了。

所以我们就从入口文件开始来看:

import applyMiddleware from "./applyMiddleware"
import bindActionCreators from "./bindActionCreators"
import combineReducers from "./combineReducers"
import compose from "./compose"
import createStore from "./createStore"
import warning from "./utils/warning"

/*
 * This is a dummy function to check if the function name ha

网易一年工作总结

Create at 2017 08 1110 min read随笔总结网易杭州

做了哪些事情

说是一年,其实也一年多了,不过这倒不重要。主要看看做了哪些事吧:

1. 改造发布流程

刚来公司的时候,白领贷的前端是基于 Riot 框架开发的系统。语言层面,使用 ES6 和 Less 开发,发布到线上是需要一个构建打包和编译的过程,不能直接部署到线上服务器。

所以项目的开发流程就是,功能开发,提交代码,本地打包,打包后的代码跟源代码一起提交测试,而后合并代码到 master 然后再在本地打包,然后上线。

这个流程非常的不合理,因为源代码和编译打包后的代码放到一块管理,本身就不合理。经常会出现,你一打包测试,我这边代码推上去就一堆冲突。所以我就想怎么来改进这个流程。

改进方案一

网易内部是有一个 omad 系统(自动部署平台)的,想着说看能不能借助这个平台干点事情。因为初来乍到,对这个部署平台不是很熟悉,就问了和这个平台接触最多的测试同学,测试同学告诉我说 omad 没有提供任何对外的接口,所以我想的可能没法实现。

这样就尴尬了,没法做线上打包

React-Redux 源码粗读

Create at 2017 08 046 min read技术ReactRedux

Overview

首先看一张图:

React-Redux

可以看到入口文件里面引入了这几个模块:

  • Provider
  • connectAdvanced
  • connect

我们就来依次看一下这几个模块

Provider

store 挂在在了 context 上面,给予了子组件访问 store 的能力。

connectAdvanced

一个用来生成 connect 的高阶函数,引用了以下模块:

import { Component, createElement } from "react"
import ho

技术选型

我们的项目主要选用以下技术开发,再配合一些其它辅助工具。

  • react
  • react-router
  • redux
  • react-redux

开发及线上环境

开发环境

由于项目是前后端分离的,所以我们需要一套完整的开发环境,需要包括以下功能:

  • 数据 Mock
  • Webpack 实施编译刷新
  • 方便前后端联调

基于这些需求,我们基于 Express, Webpack,Webpack-dev-middleware 搭建了这套完整的开发环境。

开发环境

可以看到,浏览器所有的请求都被本地的 Node.js 服务拦截。对于静态资源请求,都委托给 webpack-dev-middle