react哲学!

一、react的代码编写两种方式

1、自顶向下
当前应用比较小且比较简单的情况下,我们设计了组件模块之后,可以采用自顶向下的构建形式,最先构建上级组件,然后将静态数据通过props传入更为细粒度的组件。
这种方式比较简单方便。
2、自底向上
当前涉及的业务比较复杂,设计了组件模块之后,可以先构建精细的小模块,然后通过组装的形式,慢慢地将其构建成一个大型应用。
这种方式方便在构建细粒度的组件时,同事编写测试代码。

二、react中的props和state

props是静态数据,改动无法被监听,state的数据变化会重新触发render函数,页面重新渲染。
state是在组件内被内部管理的
props是传递给组件的,类似于函数形参,但是它也会影响页面的渲染
我们应该尽量确定UI state的最小状态,避免多余的state影响代码的可维护性
判断某块数据是静态还是动态的判断准则有以下几点:
1,该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。
2,该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。
3,你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。

三、this.setState是同步还是异步的

异步的!下面的操作最终得到的结果count最后会为1,而不是预期的3

// this.state.count 0
this.setState({ count: this.state.count + 1 })
// this.state.count 0
this.setState({ count: this.state.count + 1 })
// this.state.count 0
this.setState({ count: this.state.count + 1 })
// this.state.count 1

// 相当于
// Object.assign(
//     this.state,
//     { count: this.state.count },
//     { count: this.state.count },
//     { count: this.state.count }
// )

在执行setState时,this.state.count取值都还是0,react不会更新this.state.count,直到组件被重新渲染,当我们有这种需要依赖当前更新后的state去修改state的情况,可以通过给setState传入一个函数,而非对象来解决。

// this.state.count 0
this.setState(state => { count: this.state.count + 1 })
// this.state.count 1
this.setState(state =>{ count: this.state.count + 1 })
// this.state.count 2
this.setState(state =>{ count: this.state.count + 1 })
// this.state.count 3

setState的函数调用是分批的,会先执行updater函数,再执行下一个setState,可以解决上述state更新不及时的问题。

四、为什么要继承React.component

一个普通的无状态组件其实可以不继承React.componet,而仅仅表示为一个函数,返回模板对象
但是一个有状态的组件(props||state||context||refs)是一定要继承自ReactComponent的。

function ReactComponent(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  this.updater = updater || ReactNoopUpdateQueue;
}
ReactComponent.prototype.isReactComponent = {};
ReactComponent.prototype.setState = function (partialState, callback) {
  !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : _prodInvariant('85') : void 0;
  this.updater.enqueueSetState(this, partialState);
  if (callback) {
    this.updater.enqueueCallback(this, callback, 'setState');
  }
};

ReactComponent.prototype.forceUpdate = function (callback) {
  this.updater.enqueueForceUpdate(this);
  if (callback) {
    this.updater.enqueueCallback(this, callback, 'forceUpdate');
  }
};

通过源码可知,props,state,setState这些核心的api都是来源于ReactComponent的。

五、确定 state 放置的位置

1、首先找到承载依赖该state所有组件的共同的父组件
2、使用一个新的组件包裹该通用的父组件
3、将state提升至该父组件
4、父子组件通过props,子组件通过props修改父组件的数据,通过this.props获取数据,父组件通过向组件标签添加属性,传入props