生命周期
react生命周期分为挂载、卸载、更新三个阶段
componentWillMount(),组件将要挂载时触发的函数,它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。
componentDidMount(),组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染。
shouldComponentUpdate,是否要更新数据时触发的函数,一般用来控制这个组件是否进行更新,比如在有的state改变了之后你不想让组件重新渲染,就可以在这个方法里面进行return false去阻止更新
componentWillUpdate,将要更新数据时触发的函数,组件即将开始更新之前调用的方法,可以针对某个状态或者props修改了分别去做出不同的操作
componentDidUpdate,数据更新完成时触发的函数
componentWillReceiveProps,父组件中改变了props传值时触发的函数,用来去接受新的props后,去更新组件状态,比如子组件的ajax请求中需要的一个参数是父组件的props,这时候如果父组件的props发送变化了 ,你想要子组件也能够实时的发生变化,那么就可以在这个方法里面去利用nextProps去发送ajax请求,更新数据
componentWillUnmount,组件将要销毁时触发的函数,一般就是清除监听
简单说一下React的优势
1、React速度很快
它并不直接对DOM进行操作,引入了一个叫做虚拟DOM的概念,安插在javascript逻辑和实际的DOM之间,性能好。
reactjs定义了一套变量形式的dom模型,一切操作和换算直接在变量中,这样减少了操作真实dom,性能真是相当的高,和主流MVC框架有本质的区别,并不和dom打交道。
2、跨浏览器兼容
虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
3、一切都是component:
代码更加模块化,重用代码更容易,可维护性高。
4、单向数据流
其实reactjs的核心内容就是数据绑定,所谓数据绑定指的是只要将一些服务端的数据和前端页面绑定好,开发者只关注实现业务就行了
5、同构、纯粹的javascript
因为搜索引擎的爬虫程序依赖的是服务端响应而不是JavaScript的执行,预渲染你的应用有助于搜索引擎优化。
6、兼容性好
比如使用RequireJS来加载和打包,而Browserify和Webpack适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏。
React有状态组件和无状态组件
有状态组件又叫做类组件,用class关键字创建
无状态组件又叫做函数组件,使用props进行组件间的通信进行传值
无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props。
所有 React 组件都必须是纯函数,并禁止修改其自身 props 。
React是单项数据流,父组件改变了属性,那么子组件视图会更新。
属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改
组件的属性和状态改变都会更新视图
类组件有状态、生命周期、this而函数组件没有。
展示组件和容器组件
展示组件(persentational components)
负责展示UI,也就是组件如何渲染,具有很强的内聚性。
只关心得到数据后如何渲染
容器组件(container components)
负责应用逻辑处理,发送网络请求,处理返回数据,将处理过的数据传递给展示组件
也提供修改数据源的方法,通过展示组件的props传递给展示组件
当展示组件的状态变更引起源数据变化时,展示组件通过调用容器组件提供的方法同步这些变化
展示组件和容器组件是根据组件的意图划分组件,展示组件通常通过无状态组件实现,容器组件通过有状态组件实现
react如何渲染
首先创建一个根DOM节点,要将React元素渲染到根DOM节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上
React 中 keys 的作用是什么?
Keys是 React 用于追踪列表中元素被修改、被添加或者被移除的辅助标识
组件的State和Props
State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果
props 由父组件传递给子组件,并且就子组件而言,props 是不可变的。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起。
高阶组件(HOC)
高阶组件就是一个函数,只不过参数是一个组件,返回了一个新的组件
HOC 是纯函数,没有副作用 。纯函数:输入确定,输出就一定确定
Redux
Redux是一个应用数据流框架,解决了组件之间状态管理的问题,原理就是集中管理状态
主要有三个核心方法,action,store,reducer
构建action,通过构建一个函数,返回一个对象,需要携带type属性
构建reducer,用来响应action,通过return把数据传回store
利用createStore来构建store,构建的时候传递我们写好的reducer
利用store.subscribe()注册监听
当我们利用store.dispatch()发送一个action的时候就能触发我们的监听了,这里面利用了store.getState()拿到值
react-router
BrowserRouter 或 HashRouter 用来渲染Router所代表的组件
BrowserRouter --浏览器路由(属于后端路由) 会有一个#,通过这个# HTML 5 History进行前端跳转他的感觉像锚点
HasRouter --前端has路由(属于前端路由)很简洁没有#,但是需要 server 端支持
Route 用来匹配组件路径并且筛选需要渲染的组件
Switch 用来筛选需要渲染的唯一组件
Link 直接渲染某个页面组件
Redirect 类似于Link,在没有Route匹配成功时触发
React组件之间的通信
父子:父传子:props; 子传父:子调用父组件中的函数并传参; 兄弟:利用 redux 实现。 所有关系都通用的方法:利用PubSub.js订阅
受控组件和非受控组件
受控组件就是受React状态控制的组件,在 react 中,Input textarea 等组件默认是非受控组件(输入框内部的值是用户控制,和React无关)。但是也可以转化成受控组件,就是通过 onChange 事件获取当前输入内容,将当前输入内容作为 value 传入,此时就成为受控组件。
React diff原理
把树形结构按照层级分解,只比较同级元素
给列表结构的每个单元添加唯一的 key 属性,方便比较
React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制
选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能
HOOK
Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。
useState 通过在函数组件里调用它来给组件添加一些内部 state。React 会在重复渲染时保留这个 state。useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的 this.setState,
useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API
useContext 接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。当组件上层最近的 <MyContext.Provider> 更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext provider 的 context value 值。即使祖先使用 React.memo 或 shouldComponentUpdate,也会在组件本身使用 useContext 时重新渲染。
refs
Refs 提供了一种访问在render方法中创建的 DOM 节点或者 React 元素的方法。
Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们
当调用setState时,React render 如何工作
虚拟 DOM 渲染:当render方法被调用时,它返回一个新的组件的虚拟 DOM 结构。当调用setState()时,render会被再次调用,因为默认情况下shouldComponentUpdate总是返回true,所以默认情况下 React 是没有优化的。
原生 DOM 渲染:React 只会在虚拟DOM中修改真实DOM节点,而且修改的次数非常少——这是很棒的React特性,它优化了真实DOM的变化,使React变得更快。