Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

经典文章阅读笔记 #12

Open
chenjf5 opened this issue Sep 6, 2017 · 4 comments
Open

经典文章阅读笔记 #12

chenjf5 opened this issue Sep 6, 2017 · 4 comments

Comments

@chenjf5
Copy link
Owner

chenjf5 commented Sep 6, 2017

2017-9-6 晨读

@chenjf5 chenjf5 changed the title 阅读总结 经典文章阅读笔记 Sep 6, 2017
@chenjf5
Copy link
Owner Author

chenjf5 commented Sep 12, 2017

217-9-12晨读

未读文章

在使用react时往往会遇到一些问题

  • react性能优化问题
  • 到处使用Obejct.assign
  • 使用redux在复杂的数据流中,可能经常通过props获取的对象来提交action,因为对象是引用赋值,所以在action提交之前props里面的值已经变化了,会造成不可想象的后果

通过immutable来解决以上问题

redux-immutablejs
更多资料

使用 immutable 的边界性问题

既然这么好,Immutable.js 如何同现有的 React + Redux 技术方案进行集成呢?好在有redux-immutable(事实上还有一个叫做redux-immutablejs的库也能实现二者的集成)这么一个库,在它的帮助下,可以实现 Immutable.js 的植入。在介绍集成方案之前,我们有必要先划分数据使用的边界,就是在哪些地方使用 Javascript 原生数据结构(简称为JSD),哪些地方使用 immutable,哪些地方需要做二者的转化,如下图所示:

在 React 视图里,props 其实就来自于 Redux 维护的全局的 state 的,所以 props 中的每一项一定是 immutable 的。
在 React 视图里,组件自己维护的局部 state 如果是用来提交到 store 的, 必须为 immutable 的,否则不强制。
从视图层向同步和异步 action 发送的数据(A/B),必须是 immutable 的。
Action 提交给 reducer 的数据(C/D),必须是 immutable 的。
reducer 处理后所得 state (E)当然一定是 immutable 的。
这样似乎看起来,所有地方都是 immutable 的,但是其实异步 action 和服务器的交互当然是 JSD (F)。换句话说,我们要求,除了向服务端发送数据请求的时候,其他位置,不允许出现toJS的代码。而接收到服务端的数据后,在流转入全局 state 之前,统一转化为 immutable 数据。

为什么要做这种统一呢?是因为:

避免 JSD 和 immutable 的混用导致出错;
统一 JSD 和 immutable 的转化路径。比如你在局部 state 里不使用 immutable,但是这些局部的 state 很可能被用来通过异步 action 提交的服务端,这样在数据流里就会同时存在 JSD 和 immutable,这对于代码的维护性是一种灾难。
有的人说,我觉得成本太大,我只想在 reducer 里局部使用 immutable,于是代码变成了这样:

export default function(state, action) {
state = state.fromJS(state);
....
return state.toJS();
}
这样看起来只是让 immutable 侵入到 reducer 中,其实却是得不偿失的。因为toJS和fromJS会消耗大量的性能。

如何集成 immutable 到流程中

按照 Redux 的工作流,我们从创建 store 开始。Redux 的 createStore 可以传递多个参数,前两个是: reducers 和 initialState。

reducers 我们用 redux-immutable 提供的 combineReducers 来处理,他可以将 immutable 类型的全局 state 进行分而治之:

const rootReducer = combineReducers({
routing: routingReducer,
a: immutableReducer,
b: immutableReducer
});
当然 initialState 需要是 immutable 的:

const initialState = Immutable.Map();
const store = createStore(rootReducer, initialState);
如果你不传递 initialState,redux-immutable也会帮助你在 store 初始化的时候,通过每个子 reducer 的初始值来构建一个全局 Map 作为全局 state。当然,这要求你的每个子 reducer 的默认初始值是 immutable的。

接下来,你会发现,react-router-redux的接入也要改造,因为 routerReducer 是不兼容 immutable 的,所以你必须自定义 reducer:

import Immutable from 'immutable';
import {
LOCATION_CHANGE
} from 'react-router-redux';

const initialState = Immutable.fromJS({
locationBeforeTransitions: null
});

export default (state = initialState, action) => {
if (action.type === LOCATION_CHANGE) {
return state.set('locationBeforeTransitions', action.payload);
}
return state;
};
除此之外,还要让react-router-redux能够访问到挂载在全局 state 上的路由信息:

import {
browserHistory
} from 'react-router';
import {
syncHistoryWithStore
} from 'react-router-redux';

const history = syncHistoryWithStore(browserHistory, store, {
selectLocationState (state) {
return state.get('routing').toObject();
}
});
处理好 store 创建、reducer 集成、路由控制,接下来改处理 connect 链接,因为 connect 本身只支持 plain Object,所以需要将数据转成 connect 能支持的格式。但这并不意味着你要这么干:

@connect(state => state.toJS())
这种传递方式本质上和上面提及的只在 reducer 里使用 immutable 是一样一样的,会带来巨大的性能开销。正确的方式是,将绑定到 props 的 state 转化为属性为 immutable 的 Object 对象:

@connect(state => state.toObject())
当然,以上的例子是整个转化过去,你也可以按需绑定对应组件所关心的 state。

细心的人可能会发现,在使用 immutable 维护全局的 state 的情况下,组件 props 的校验也需要与时俱进,使用 immutable 类型校验,这就需要我们 import 专门针对 immutable 类型进行校验的库:react-immutable-proptypes,使用方法基本上和普通的 PropTypes 一致:

propTypes: {
oldListTypeChecker: React.PropTypes.instanceOf(Immutable.List),
anotherWay: ImmutablePropTypes.list,
requiredList: ImmutablePropTypes.list.isRequired,
mapsToo: ImmutablePropTypes.map,
evenIterable: ImmutablePropTypes.iterable
}
与此同时,产生defaultProps的地方应该为:

fromJS({
prop1: xxx,
prop2: xxx,
prop3: xxx
}).toObject();
性能优化
https://github.com/lcxfs1991/blog/issues/8173这篇文章写的很好了。其实关键点就在拆包和 shouldComponentUpate。

使用他提供的 decorator 来减少 render 的触发。

@chenjf5
Copy link
Owner Author

chenjf5 commented Sep 13, 2017

2017-9-13晨读

不错的文章

学习BFC
精读 Immutable 结构共享

阅读总结

Redux进阶系列3:如何设计action、reducer、selector

主要把state拆分成子redux,并且把子redux和对应的子action放在一个文件夹,最后通过combineReducers合并。
types定义了app模块使用的action types,每一个action type的值以模块名作为命名空间,以避免不同模块的action type冲突问题。actions定义了该模块使用到的action creators。我们没有直接导出每一个action type和action creator,而是把所有的action type封装到types常量,所有的action creators封装到actions常量,再导出types和actions这两个常量。这样做的好处是方便在其他模块中引用。

// 所在文件:app.js
//action types
export const types = {
  const START_FETCH  : 'app/START_FETCH',
  const FINISH_FETCH : 'app/FINISH_FETCH',
  const SET_ERROR : 'app/SET_ERROR'
}

//action creators
export const actions = {
  startFetch: () => {
    return {type: types.START_FETCH};
  },
  finishFetch: ()=> {
    return {type: types.FINISH_FETCH};
  },
  setError: (error)=> {
    return {type: types.SET_ERROR, payload: error};
  }
}

WebRTC会成主流

webrtc是做流媒体的新技术,提供了浏览器和浏览器进行通信的功能,主流新版浏览器都支持。

@chenjf5
Copy link
Owner Author

chenjf5 commented Sep 21, 2017

2017-9-21 晨读

1、数学运算
Web Worker最简单的应用就是用来做后台计算,对CPU密集型的场景再适合不过了。
2、图像处理
通过使用从中获取的数据,可以把图像分割成几个不同的区域并且把它们推送给并行的不同Workers来做计算,对图像进行像素级的处理,再把处理完成的图像数据返回给主页面。
3、大数据的处理
目前mvvm框架越来越普及,基于数据驱动的开发模式也越愈发流行,未来大数据的处理也可能转向到前台,这时,将大数据的处理交给在Web Worker也是上上之策了吧。

ES2015 / ES2016/ ES2017 等等 ES20xx 时代的 presets 通通被替换
useBuiltIns 选项与 Polyfill
这是一个关于 Polyfill 的选项,个人认为这是此次迁移后带来的最大便利,当然首先你仍然需要额外安装 babel-polyfill(是的,你不再需要额外的 transform)

@chenjf5
Copy link
Owner Author

chenjf5 commented Sep 26, 2017

2017-926 晨读

<div data-msg="Open this file in Github Desktop">  
hover
</div>
div{
width:100px;
border:1px solid red;  
position:relative;
}
div:hover:after{
content:attr(data-msg);
position:absolute;
font-size: 12px;
width:200%;
line-height:30px;
text-align:center;
left:0;
top:25px;
border:1px solid green;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant