react知识点整理 2019-08-17

2019-08-17  本文已影响0人  讨厌西红柿

周末加班,临时整理些react有关的东西

1、immutable

一旦创建就不可修改的数据类型,对immutable对象的任何修改、添加或删除操作都会返回一个新的immutable对象。其实现原理是Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时要保证旧数据同时可用且不变。同时为了避免deepcopy(深拷贝)带来的性能损耗,immutable使用了结构共享Structural Sharing,即如果对象树中的一个节点发生变化,只修改此节点和受影响的父节点,其他节点则进行共享。

Immutable优点

缺点:容易与原生对象搞混

2、key的作用是什么

key是react用来追踪节点被修改、添加或移除的标识,react的diff算法会根据节点的key值判断该节点是否需要刷新,以减少不必要的渲染。一般适用在列表组件的子项里,需保证同级元素key值的唯一性。在某些时候,甚至能直接改变组件的key值来达到重新渲染整个组件的目的。

3、调用setState发生了什么

setState一般用来更新数据,重新渲染DOM元素。调用setState后,react会将参数对象合并到当前状态,发起一个和解过程(reconciliation),以高效的方式生成一个新的元素树,之后通过diff算法计算两个元素树的不同点,进行最小差异化渲染。

4、生命周期

constructor 初始化
componentWillMount
componentDidMount
shouldComponentUpdate
componentWillUnmount
render
componentWillReceiveProps

5、diff算法

1、把树形结构按层级分解,只比较同层级元素
2、按照key值来比较同级元素
3、react只匹配相同class的component,不同则直接删除然后挂载新的节点
4、合并操作
5、选择性的渲染

6、redux

三个原则

整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。

唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

由用户交互触发 -----> action ----(store.dispatch(action))---- > store ----(store调用reducer返回新的state)-----> reducer -----> view刷新

redux原理、同步异步如何实现、中间件的原理
中间件:react-logger、react-thunk。

异步action实现:

在store.dispatch中传入一个函数执行,这个函数返回另一个函数,参数有两个,一个是dispatch、另一个则是getState,然后在这个函数中进行异步操作,分别在异步开始、成功、失败步骤中调用传入的dispatch方法,传入相应的action;因为需要dispatch一个函数,所以需要使用react-thunk配合。

applyMiddleware的实现原理:

使用柯里化函数来保存参数,如果有中间件则会传入createStore,在返回的函数里面构建store,生成每个中间件都需要的dispatch和getState,再遍历middlewares中间件数组,分别调用每个中间件一次。
第三个参数通过applyMiddleware添加中间件。

通过connect(mapStateToProps, mapDispatchToProps)(组件) 可以访问到store里面特定的state和action,避免因为监听所有state变化造成性能问题。在mapDispatchToProps里面可以用bindActionCreators把dispatch和action creator绑定在一起,这样就直接调用action creator函数就相当于直接dispatch了

7、Hooks

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。
React内置两种hook:stateHook与effectHook。

import React, { useState } from 'react';

function Example() {
const [count, setCount] = useState(0);
return (
       <div>
         <p>You clicked {count} times</p>
         <button onClick={() => setCount(count + 1)}>
         Click me
        </button>
      </div>
    );
  }

stateHookfunction组件提供state支持,使函数组件可以使用state更新数据。useState参数只有一个,就是初始state,其返回一个数组包含变量名与更新函数,这里使用了数组解构获取countsetCount,之后就可以直接使用setCount更新count的值。

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

effectHook是每次组件更新都会调用的一个hook,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdatecomponentWillUnmount 这三个函数的组合。也可以在useEffectHook中返回一个函数,做一些扫尾工作,React 将会在执行清除操作时调用它。

useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

userEffectHook还能传入第二个参数,已达到性能优化的目的。

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新

第二个参数为一个数组,表示仅当数组中的数据发生改变是,才执行effect

8、Context

避免繁琐的props或者state的逐级传递,可以跨组件传递数据。通过createContext创建上下文对象,context对象主要是有provide(生产者)consumer(消费者)。使用provide包裹父组件,传入value值;consumer包裹子组件,并使用function child的方式返回需要渲染的React节点,完成context订阅。Provider 及其内部 consumer 组件都不受制于shouldComponentUpdate 函数。

<MyContext.Consumer>
  {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>

9、refs

refs提供了一种访问dom节点或react element的方法,我们可以使用它来播放视频、管理焦点、触发命令式动画等操作。

10、webpack

四个核心概念:

1. 入口(entry)

告诉webpack从哪里开始打包,从入口开始webpack会找出所有依赖的文件。可以有多个入口。

entry: {
    main: './path/to/my/entry/file.js'
  }
2. 输出(output)

告诉webpack在哪里输出它所创建的bundle,以及如何命名这些文件。我们通过 output.filename 和 output.path 属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里

output: {
    filename: 'my-first-webpack.bundle.js'
  },
3. loader

将所有类型的文件转换为 webpack 能够处理的有效模块

在 webpack 的配置中 loader 有两个目标:

module: {
    rules: [
      { test: /\.txt$/, use: 'raw-loader' }
    ]
  }
4. 插件(plugins)

loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

plugins: [
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]

11、高阶组件HOC

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。

具体而言,高阶组件是参数为组件,返回值为新组件的函数。

12、容器组件和展示组件

展示组件其实就相当于可控状态组件,由外部控制其界面展示,没有内部state
容器组件为展示组件或其他组件提供数据和方法,通常由高阶组件生成,比如Redux里的connect(),Relay里的createContainer()。

上一篇 下一篇

猜你喜欢

热点阅读