全栈工程师成神之路--React

@wanqiuz 2018-06-30 07:18:15发表于 wanqiuz/blog-articles 全栈工程师成神之路

⭐️ React v15 组件生命周期

1814354-4bf62e54553a32b7

⭐️ Controlled Component 与 Uncontrolled Component 区别

受控组件(Controlled Component)代指那些数据交由 React 控制的组件。
非受控组件(Uncontrolled Component)则是由DOM存放表单数据。
受控组件优势:考虑表单验证、、强制输入格式、时间旅行等功能支持,并且从繁琐的DOM中解放出来。

⭐️ React Key

react中的key是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key props),而是给react自己用的。
key不是用来提升react的性能的,不过用好key对性能是有帮组的。
key属性的使用场景最多的还是由数组动态创建的子组件的情况。由数组创建的子组件必须有key属性,是强制要求的,只不过react为按要求来默认上帮我们做了,它是以数组的index作为key的,但index作为key是一种反模式。
key的值要稳定唯一。

⭐️ React中setState

setState更新状态是同步还是异步?

在React中有三种事件处理,分别为
(1) 由React引发的事件处理(比如通过onClick引发的事件处理)。-----异步更新state
(2) 绕过React通过addEventListener直接添加的事件处理函数。-----同步更新state
(3) 通过setTimeout/setInterval产生的异步调用。-----同步更新state

setState异步更新到底发生了什么?

当调用 setState 时,React将传递给 setState 的对象合并到组件的当前状态。然后调用shouldComponentUpdate生命周期方法。如果该方法返回true,则会构建一个新的 React 元素树,React 会将这个新树与上一个元素树用DIFF算法比较,然后高效的更新元素树。

setState第二个可选参数是什么以及它的作用?

它是一个回调函数,在setState调用之后,以及component re-render后才执行.

下列代码有什么错误?

this.setState((prevState, props) => {
  return {
    streak: prevState.streak + props.count
  }
})

没错。它不太常用,但是你可以传递一个函数给setState(函数是一等公民),这个函数接收前一个时刻的state和props,并且返回一个新state。虽然这个用法不太常见,但是如果你想基于先前的state设置新的state,强烈建议这么做。

⭐️ Class Component or Functional Component

如果一个component有state或者lifecycle method,用class component,否则用Functional Component。

⭐️ 在哪个lifecycle method进行AJAX请求

AJAX 请求应该在 componentDidMount 生命周期事件中。 有两个原因:
(1) Fiber,是React v16实施的新的和解算法,将有能力根据需要启动和停止渲染,以获得性能优势。其中一个取舍之一是 componentWillMount 。 React 可以在不同的时间调用 componentWillMount很多次,这个生命周期随时可能被打断。(进入到render周期就不会被打断了)这显然是AJAX请求的不好的方式。
(2) 不能保证在组件挂载之前,AJAX请求将无法 resolve。如果AJAX请求在组件挂载之前resolve了,那意味着会在一个未挂载的组件上 SetState,参考React生命周期,它会进入到shouldComponentUpdate中,此时会报错。 在 componentDidMount 中执行 AJAX 将保证组件会被更新。

⭐️ Element和Component区别?

React element是一个表示UI的对象。
React component是一个函数或者组件,接受输入,并返回React element(通过JSX 转化成createElement调用)。

⭐️ 为什么用React.Children.map(props.children, () => {})而不是props.children.map(() => {})

因为props.children并不保证是数组,所以若props.children不是数组,props.children.map会报错,而React.Children.map考虑了props.children是对象或者数组的情况。

⭐️ createElement和cloneElement区别?

createElement是JSX转为而来的,是用来创造React Element的。cloneElement是用来拷贝React Element,并且传递新属性的。

⭐️ Redux

Redux是什么?

Redux是一个库,是一个可预测的状态容器。

Redux三大原则

1)单一数据源(整个应用状态都保存在一个对象中,可以随时用来持久化,也为服务端渲染提供了可能,至于数据源庞大的问题,Redux提供了combineReducers来化解)
2)状态是只读的(immutable思想)
3)状态的修改均是由纯函数完成的(通过纯函数Reducer来修改状态,是应用变得简单、可测试,可以实现时间旅行(time travel)的调试方式)

Redux核心API

  • Redux核心是一个store,这个store由Redux提供的最核心的API createStore(reducers[, initialState])方法生成,store对象本身有四个方法getStore(),dispatch(action),subscribe(listener),replaceReducer(nextReducer)。
  • 在Redux中,负责响应action并修改数据的角色就是reducer。reducer本质上是一个函树,函数签名为reducer(previousState, action) => newState

Redux和React绑定

需要使用react-redux库,之所以不放在一起,是为了实现平台无关性,react-redux提供了一个组件和一个API帮助Redux和React进行绑定,一个是React组件,接受一个store对象作为props,它是整个Redux应用的顶层组件,一个是函数connect(),提供了整个React应用的任意组件中获取store中数据的功能。

Redux middleware

作者Dan Abramov描述Redux middleware为,它在dipatch action和action抵达reducer之间增加了第三方的功能扩展。

Redux异步流

1)使用middleware简化异步请求
redux-thunk, redux-promise, redux-composable-fetch
2) 使用middleware处理复杂异步流
轮训,多异步串联,redux-saga

Redux与路由

1)所有SPA都必然会由一个路由系统作为整个系统的入口,路由的基本原理即使保证View和URL同步,可以把React Router中的Router组件看成一个方法,location作为参数,返回的结果同样是view。

  • 声明式的路由
  • 嵌套路由及路径匹配
  • 支持多种路由切换方式

2)React Router Redux提供了简单的API syncHistoryWithStore来完成Redux store的绑定,当然同时还需要对store进行增强,使能识别响应的action,最后就可以用store.dipatch来分发一个路由变动了。

Redux中的组件

项目 展示型组件 容器性组件
目的 长什么样子 干什么用
是否感知Redux
要获取数据 从this.props中获取 使用connect从Redux状态树种获取
要改变数据 调用从this.props中的action creator 直接分发任意action
实际创建于 开发者 由React Redux创建

⭐️ webpack

什么是webpack

webpack是收把项目当作一个整体,通过一个给定的的主文件,webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包成一个或多个浏览器可识别的js文件

webpack和grunt/gulp区别

他和其他的工具最大的不同在于他支持code-splitting、模块化(AMD,ESM,CommonJs)、全局分析。

什么是bundle,什么是chunk,什么是module?

bundle是由webpack打包出来的文件,chunk是指webpack在进行模块的依赖分析的时候,代码分割出来的代码块。module是开发中的单个模块。

什么是Loader?什么是Plugin?

1)Loaders是用来告诉webpack如何转化处理某一类型的文件,并且引入到打包出的文件中
2)Plugin是用来自定义webpack打包过程的方式,一个插件是含有apply方法的一个对象,通过这个方法可以参与到整个webpack打包的各个流程(生命周期)。

如何可以自动生成webpack配置?

webpack-cli /vue-cli /etc ...脚手架工具

什么是模块热更新?

模块热更新是webpack的一个功能,他可以使得代码修改过后不用刷新浏览器就可以更新,是高级版的自动刷新浏览器。

什么是长缓存?在webpack中如何做到长缓存优化?

浏览器在用户访问页面的时候,为了加快加载速度,会对用户访问的静态资源进行存储,但是每一次代码升级或是更新,都需要浏览器去下载新的代码,最方便和简单的更新方式就是引入新的文件名称。在webpack中可以在output纵输出的文件指定chunkhash,并且分离经常更新的代码和框架代码。通过NameModulesPlugin或是HashedModuleIdsPlugin使再次打包文件名不变。

什么是Tree-shaking?CSS可以Tree-shaking吗

Tree-shaking是指在打包中去除那些引入了,但是在代码中没有被用到的那些死代码。在webpack中Tree-shaking是通过uglifySPlugin来Tree-shaking JS。Css需要使用Purify-CSS。

有哪些常用的loaders

babel-loader: 让下一代的js文件转换成现代浏览器能够支持的JS文件。
babel有些复杂,所以大多数都会新建一个.babelrc进行配置
css-loader,style-loader:两个建议配合使用,用来解析css文件,能够解释@import,url()如果需要解析less就在后面加一个less-loader
file-loader: 生成的文件名就是文件内容的MD5哈希值并会保留所引用资源的原始扩展名
url-loader: 功能类似 file-loader,但是文件大小低于指定的限制时,可以返回一个DataURL事实上,在使用less,scss,stylus这些的时候,npm会提示你差什么插件,差什么,你就安上就行了

有哪些常用的plugins