mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-25 12:27:15 +00:00
docs: SSL/TLS
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
# React核心技术剖析
|
||||
|
||||
|
||||
# React核心技术剖析
|
||||
|
||||
## 虚拟 Dom
|
||||
|
||||
@@ -17,19 +15,14 @@ React 性能高效的一个原因就是 Virtual Dom 的应用和 diff 之后的
|
||||
|
||||
- https://www.infoq.cn/article/AiQMbjI0oXZ1UrueiBze
|
||||
|
||||
|
||||
|
||||
## Diff 算法
|
||||
|
||||
diff 算法大体上做的事情就是拿到前后2个状态的 Virtual Dom ,然后按照同层级节点去比较,发现当前的节点有差异,则不向下进行比较,直接将当前节点重新渲染。
|
||||
|
||||
|
||||
|
||||
## JSX 的原理
|
||||
|
||||
JSX 做的事情是为了告诉 React 样式模版是什么。本质上来说 JSX 就是 `React.createElement` 的可读性更强的版本。`React.createElement` 接收三个参数。参数1:标签类型;参数2:属性;参数3:子元素。
|
||||
|
||||
|
||||
```Javascript
|
||||
render () {
|
||||
const { content } = this.props
|
||||
@@ -42,14 +35,10 @@ render () {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 生命周期
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 状态管理
|
||||
|
||||
Redux 设计上是对 Flux 的改进,增加了 reducer。Flux 就不再介绍了。解决了各个组件之间数据传递的复杂问题。先看看 Redux 进行状态管理的一个流程吧。
|
||||
@@ -67,51 +56,55 @@ Redux 设计上是对 Flux 的改进,增加了 reducer。Flux 就不再介绍
|
||||
### 开发经验
|
||||
|
||||
- Redux 中每次创建 action 都需要设置 type,type 为字符串,所以很容易写错,且各个组件都直接用字符串的方式创建 action 的 type 会比较分散,字符串拼写错误造成的 bug 难以排查,所以需要一个地方集中统一处理 action type。思路为在 `src/store` 文件夹下面创建 actionTypes.js 文件夹,创建全部大写的变量,然后导出。
|
||||
<details>
|
||||
|
||||
<details>
|
||||
<summary>展开示例代码</summary>
|
||||
|
||||
```javascript
|
||||
export const CHANGE_INPUT_VALUE = 'change_input_value';
|
||||
export const ADD_TODO_ITEM = 'add_todo_item';
|
||||
export const DELETE_TODO_ITEM = 'delete_todo_item';
|
||||
export const INIT_TODO_DATA = 'init_todo_data';
|
||||
export const GET_INIT_LIST = 'get_init_list'
|
||||
```
|
||||
</details>
|
||||
|
||||
```javascript
|
||||
export const CHANGE_INPUT_VALUE = 'change_input_value';
|
||||
export const ADD_TODO_ITEM = 'add_todo_item';
|
||||
export const DELETE_TODO_ITEM = 'delete_todo_item';
|
||||
export const INIT_TODO_DATA = 'init_todo_data';
|
||||
export const GET_INIT_LIST = 'get_init_list'
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- Redux 使用的时候全局工程会创建很多 action,所以和上面的思想一样,需要集中统一处理,符合“收口原则”、“单一原则”。做法就是在 `src/store` 目录下创建一个 actionCreators.js 文件。然后在里面引入 actionType.js,根据业务导出几个产生 action 的函数。
|
||||
<details>
|
||||
<summary>展开示例代码</summary>
|
||||
|
||||
```javascript
|
||||
import { CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM } from './actionTypes'
|
||||
|
||||
export const getInputChangeAction = (value) => {
|
||||
return {
|
||||
type: CHANGE_INPUT_VALUE,
|
||||
value
|
||||
}
|
||||
};
|
||||
|
||||
export const getAddTodoItemAction = () => ({
|
||||
type: ADD_TODO_ITEM
|
||||
});
|
||||
|
||||
export const getDeleteTodoItemAction = (value) => ({
|
||||
type: DELETE_TODO_ITEM,
|
||||
value
|
||||
});
|
||||
```
|
||||
</details>
|
||||
- store 发现 action 提交的数据是函数类型的时候,会自动执行函数
|
||||
|
||||
<details>
|
||||
<summary>展开示例代码</summary>
|
||||
|
||||
```javascript
|
||||
import { CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM } from './actionTypes'
|
||||
|
||||
export const getInputChangeAction = (value) => {
|
||||
return {
|
||||
type: CHANGE_INPUT_VALUE,
|
||||
value
|
||||
}
|
||||
};
|
||||
|
||||
export const getAddTodoItemAction = () => ({
|
||||
type: ADD_TODO_ITEM
|
||||
});
|
||||
|
||||
export const getDeleteTodoItemAction = (value) => ({
|
||||
type: DELETE_TODO_ITEM,
|
||||
value
|
||||
});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- store 发现 action 提交的数据是函数类型的时候,会自动执行函数
|
||||
|
||||
### 核心思想
|
||||
|
||||
- 单一数据源:整个应用的 state 被存储在一棵 Object tree 中,并且这个 object tree 只存在于唯一一个 store 中
|
||||
- State 是只读的:唯一改变 state 的方式就是触发 action,action 是描述已发生时间的普通对象
|
||||
- 使用纯函数来执行修改:为了描述 action 如何改变 state tree,你需要根据业务编写 reducer
|
||||
|
||||
|
||||
### Redux-thunk
|
||||
|
||||
Redux-thunk 是 redux 里面常用的一个中间件。中间件?针对谁和谁的中间?对 action 和 store 的中间件。本来 action 只可以返回一个对象,灵活性较低,但是采用了 redux-thunk 之后,action 不仅可以传递对象,还可以传递函数。 action 通过 dispatch 传递给 store。 dispatch 判断 action 的类型,如果是对象则直接传递;如果是函数则直接执行。
|
||||
@@ -119,16 +112,17 @@ Redux-thunk 是 redux 里面常用的一个中间件。中间件?针对谁和
|
||||

|
||||
|
||||
- 异步函数不应该放在组件的生命周期函数里面。复杂的业务逻辑和异步函数适合拆分。目前主流的解决方案有2种中间件:redux-thunk、redux-saga。采用不同的策略
|
||||
|
||||
- redux-thunk:将异步任务分离到 action 中。
|
||||
- redux-saga:将异步任务拆分到单独的文件中,而不是 action 里面。
|
||||
相比较而言,redux-saga 比 redux-thunk 功能更加强大,提供的有用的功能更多。
|
||||
相比较而言,redux-saga 比 redux-thunk 功能更加强大,提供的有用的功能更多。
|
||||
|
||||
- react-redux:网上经常说的 react-redux 里面既有 UI 组件、也有容器组件。connect 方法将一个 UI 组件(傻瓜组件) 和 store、dispatch 联合在一起后,connect 函数的返回结果就是一个容器组件
|
||||
|
||||
```javascript
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TodoListReactRedux)
|
||||
```
|
||||
|
||||
|
||||
## 组件的写法
|
||||
|
||||
```javascript
|
||||
@@ -142,20 +136,20 @@ class Welcome extends React.Component {
|
||||
return <h2>hello, {this.props.name}</h2>;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
###
|
||||
|
||||
## 开发tips
|
||||
|
||||
- 不要直接操作 state,只能通过 setState 操作数据;props 是只读的
|
||||
|
||||
- setState 的时候如果依赖之前的 state 数据,那么 setState 第一个参数可以更改为函数方式,这个函数有2个参数
|
||||
|
||||
```javascript
|
||||
setState((state, props) => ({ count: state.count + props.increment }));
|
||||
```
|
||||
|
||||
- 路由设置的时候,我们经常会设置路径。每个路径匹配到具体的页面资源会呈现出来。但是在一开始的时候会遇到疑问,为什么我在浏览器里面输入了 “/home”。但是出来的内容还是 “/” 皮配到的页面,后来知道了还可以设置 **exact** 属性可以精确控制。
|
||||
|
||||
```javascript
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
@@ -169,10 +163,11 @@ class Welcome extends React.Component {
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
```
|
||||
|
||||
- 在 React 的开发中,有2个名字会很熟悉:傻瓜组件、容器组件。假如一个 TodoList 的 UI 部分和逻辑处理部分都在 一个 TodoList 组件里面进行解决,那么代码将会冗余且不易测试,为了解决此问题,我们常常会将 UI 部分单独抽离出去,只负责显示出 UI,这种组件叫做傻瓜组件(UI组件)。页面需要的数据或者点击事件的处理函数都通过 **props** 的形式由父组件传递下来。父组件在渲染的时候只负责逻辑的展示,在自身的 render 函数里面调用之前分离出去的傻瓜组件(UI组件)。为了保证代码的健壮性和安全性,UI 组件需要的数据和函数都通过 props 传递,且加一个 propTypes 安全校验。
|
||||
|
||||
- 无状态组件:当一个组件只有 render 函数的时候,这样的组件被叫做**无状态组件**。做法就是将 `class TodoList extends React.Dom` 修改成一个函数。函数形式的无状态组件效率比较高。因为类形式的组件,会有生命周期等函数,效率会低一些。
|
||||
|
||||
|
||||
```javascript
|
||||
const TodoListUI = (props) => {
|
||||
return <div>props.name</div>;
|
||||
@@ -180,6 +175,7 @@ class Welcome extends React.Component {
|
||||
```
|
||||
|
||||
- export default 在一个模块里面只可以存在一个,使用的时候不需要 `{}`;export 可以存在多个,使用的时候需要使用 `{}`
|
||||
|
||||
```javascript
|
||||
export const person = {
|
||||
name: 'lbp',
|
||||
@@ -192,15 +188,17 @@ class Welcome extends React.Component {
|
||||
import { person, testing } from './store'
|
||||
```
|
||||
|
||||
|
||||
## React 和 Vue 的对比
|
||||
|
||||
- React 是单向数据流,数据是不可变的。Vue 是双向数据流,数据是可以变的。什么意思?看下面的例子
|
||||
Vue.js
|
||||
|
||||
```javascript
|
||||
<input type="text" maxlength="11" autocomplete="off" class="form-control input-lg input-flat input-flat-user" placeholder="请输入手机号码" name="resetmobile" v-validate="'required|resetmobile'" v-model="resetmobile">
|
||||
```
|
||||
|
||||
React.js
|
||||
|
||||
```javascript
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -209,7 +207,7 @@ class Welcome extends React.Component {
|
||||
this.handleInputChange = this.handleInputChange.bind(this)
|
||||
store.subscribe(this.handleStateChange);
|
||||
}
|
||||
|
||||
|
||||
<input placeholder="things to do..."
|
||||
style={ { width: 300, marginRight: 20 } }
|
||||
value={props.inputValue}
|
||||
@@ -231,6 +229,7 @@ class Welcome extends React.Component {
|
||||
this.setState(store.getState());
|
||||
}
|
||||
```
|
||||
|
||||
可以看出来,Vue 通过简单的一个内置命令 `v-model` 将 model 和 view 双向绑定了起来,数据是双向的。model 改变 view 自动刷新;用户在 input 写了文字,model 的值也自动改变。React 先设置一个 input 组件,监听用户的输入事件(onChange),然后在 onChange 里面拿到当前输入框里面的数据,然后你可以直接 setState 去操作数据,setState 后才会触发 render 函数,dom 才会跟着更新。
|
||||
|
||||
- React 比 Vue 更加适合构建大型项目。
|
||||
@@ -238,5 +237,4 @@ class Welcome extends React.Component {
|
||||
|
||||
- Vue 设计思想:How easy it can be。React:How corrct it can be 和 all in js(css写法也在用 js 控制,比如 styled-component)
|
||||
|
||||
|
||||
在 React、React Native、Vue、Weex、Flutter 等声明式开发思想的框架下,UI = F(state)。一个状态唯一对应一个 UI(但一个 UI 不一定对应一个 state),关心 state 即可
|
||||
Reference in New Issue
Block a user