We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
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
setState原理,什么时候同步,什么时候异步
JSX原理,为什么自定义的React组件必须大写
虚拟DOM,diff算法
生命周期(16版本之前和之后的)
React事件机制
fiber
mixin、HOC、render props、hooks
immber和immutable
受控组件和非受控组件区别
redux,redux 和 mobx 区别,为什么选择 redux
Vue和React的区别
这里的“异步”不是说异步代码实现,而是说 React会收集变更,然后在统一更新。
在React中,如果是由React引发的事件处理(比如通过 onClick引发的事件处理),调用 setState 不会同步更新this.state,除此之外的setState调用会同步执行this.state。所谓"除此之外”,指的是绕过React通过 addEventListener 直接添加的事件处理函数,还有通过 setTimeout/setInterval产生的异步调用。
在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。
实际上,JSX仅仅只是 React.createElement(component, props, ...children)函数的语法糖。如下JSX代码
React.createElement(component, props, ...children)
<MyButton color="blue" shadowSize={2}> Click Me </MyButton>
会编译为
React.createElement(MyButton, { color: "blue", shadowSize: 2 }, "Click Me");
如果没有子节点,你还可以使用自闭合的标签形式,如
<div className="sidebar" />
React.createElement("div", { className: "sidebar" });
可以直接在 babeljs中尝试。
React.createElement(component, props, ...children)的第一个参数 component的类型是 string/ReactClass type
简而言之,babel在编译过程中会判断 JSX 组件的首字母,如果是小写,则当做原生的DOM标签解析,就编译成字符串。如果是大写,则认为是自定义组件,编译成对象。
虚拟DOM 就是使用一个 原生的JavaScript对象来描述 一个DOM节点。
<div id="wrap"> <p class="text">好好学习,天天向上</p> </div>
使用虚拟DOM表示如下:
const element = { // 标签名 tagName: 'div', properties: { id: 'wrap', }, children: [ { tagName: 'p', properties: { class: 'text', children: ['好好学习,天天向上'] }, } ] }
其核心是基于两个简单的假设:
基于以上这两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。
React’s diff algorithm
16版本之前的生命周期
constructor -> componentWillMount -> render -> componentDidMount
componentWillReceiveProps(newProps) -> shouldComponentUpdate((nextProps, nextState))(如果返回true) -> componentUillUpdate(nextProps, nextState) -> render -> componentDidUpdate(prevProps, prevState)
shouldComponentUpdate((nextProps, nextState))(如果返回true) -> componentUillUpdate(nextProps, nextState) -> render -> componentDidUpdate(prevProps, prevState)
componentWillUnmount
16版本之后的生命周期
constructor -> getDerivedStateFromProps(nextProps, prevState) -> render -> componentDidMount
getDerivedStateFromProps(nextProps, prevState) -> shouldComponentUpdate((nextProps, nextState))(如果返回true) -> render -> getSnapshotBeforeUpdate(prevProps, prevState) -> componentDidUpdate(prevProps, prevState)
// 传统的HTML <button onclick="getCount()"> 点击 </button> // 在react中 <button onClick={getCount}> 点击 </button>
preventDefault
function invokeGuardedCallback(name, func, a) { try { func(a); } catch (x) { if (caughtError === null) { caughtError = x; } } }
回调函数是直接调用的,如果不手动绑定 this,获取到的 this为 undefined
render之前的生命周期,即将被废弃 componentWillMount componentWillUpdate componentWillReceiveProps
在16.x版本之前,每个生命周期在加载或更新过程中只会调用一次,因为新的fiber架构允许在 diff的时候不停的中断执行,所有render之前的声明周期可能会执行很多次。
fiber分为两部分
js是单线程的,如果当前在执行一个很耗时的任务,那么剩下的任务就要等当前任务执行完之后再执行。16.x版本之前,React的更新过程是同步的,当React决定要更新DOM时,从diff到更新DOM,一气呵成。这种就会有一个问题,更新的组件比较复杂并且多(层级深等)的时候,此时如果用户点击了页面某个按钮,可能会因为正在批量更新DOM还未进行完成,按钮无法响应的问题。 fiber架构第一个阶段是分片的,将一个任务成很多个小的任务去执行,每次只执行一个小的任务,然后去看一下有没有优先级更高的任务,如果有,则去执行优先级更好的任务,如果没有,接着再执行下一小段任务。 为什么第二个阶段,更新渲染DOM必须是同步的呢,这个也很好理解。你总不能渲染了一半的时候去干其他的事情吧。
vue和react中都曾用过mixin(react目前已经抛弃) mixin(混入)本质上就是将对象复制到另一个对象上。
const mixin = function (obj, mixins) { const newObj = obj; newObj.prototype = Object.create(obj.prototype); for(let prop in mixins) { if(mixins.hasOwnProperty(prop)) { newObj.prototype[prop] = mixins[prop]; } } return newObj; } const obj = { sayHello() { console.log('hello'); } }; const otherObj = function() { console.log('otherObj'); } const Obj = mixin(otherObj, obj); const a = new Obj(); // otherObj a.sayHello(); // hello
mixin存在的几个问题:
HOC是React社区提出的新的方式用来取代mixin的。 高阶函数是函数式编程中一个基本的概念,它描述了一种这样的函数:接受函数作为输入,或是返回一个函数,比如 map, reduce等都是高阶函数。 高阶组件( higher-order component),类似于高阶组件接受一个组件作为参数,返回另一个组件。
function getComponent(WrappedComponent) { return class extends React.Component { render() { return <WrappedComponent {...this.props}/>; } }; }
HOC的优点为:
HOC的问题是:
render props: 通过props接受一个返回react element 的函数,来动态决定自己要渲染的结果
<DataProvider render={data => ( <h1>Hello {data.target}</h1> )}/>
React Router中就用到了 Render Props
<Router> <Route path="/home" render={() => <div>Home</div>} /> </Router>,
它有哪些问题呢
具体实现就是通过一个函数来封装跟状态有关的逻辑,将这些逻辑从组件中抽取出来。而这个函数中我们可以使用其他的Hooks,也可以单独进行测试,甚至将它贡献给社区。
import { useState, useEffect } from 'react'; function useCount() { const [count, setCount] = useState(0); useEffect(() = { document.title = `You clicked ${count} times`; }); return count }
hooks的引入就是为了解决上面提到的这么问题,因为 使用函数式组件,我们在开发组件的时候,可以当做平常写函数一样自由。
函数复用是比较容易的,直接传不同的参数就可以渲染不同的组件,复杂组件实现,我们完全可以多封装几个函数,每个函数只单纯的负责一件事。而且很多公用的代码逻辑和一些场景我们可以抽出来,封装成自定义hooks使用,比如 Umi Hooks库封装了很多共用的逻辑,比如 useSearch,封装了异步搜索场景的逻辑;比如 useVirtualList,就封装了虚拟列表的逻辑。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
目录
setState原理,什么时候同步,什么时候异步
JSX原理,为什么自定义的React组件必须大写
虚拟DOM,diff算法
生命周期(16版本之前和之后的)
React事件机制
fiber
mixin、HOC、render props、hooks
immber和immutable
受控组件和非受控组件区别
redux,redux 和 mobx 区别,为什么选择 redux
Vue和React的区别
一.setState原理,什么时候同步,什么时候异步
这里的“异步”不是说异步代码实现,而是说 React会收集变更,然后在统一更新。
在React中,如果是由React引发的事件处理(比如通过 onClick引发的事件处理),调用 setState 不会同步更新this.state,除此之外的setState调用会同步执行this.state。所谓"除此之外”,指的是绕过React通过 addEventListener 直接添加的事件处理函数,还有通过 setTimeout/setInterval产生的异步调用。
在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。
二.JSX原理,为什么自定义的React组件必须大写
JSX原理
实际上,JSX仅仅只是
React.createElement(component, props, ...children)
函数的语法糖。如下JSX代码会编译为
如果没有子节点,你还可以使用自闭合的标签形式,如
会编译为
可以直接在 babeljs中尝试。
为什么自定义的React组件必须大写
React.createElement(component, props, ...children)
的第一个参数 component的类型是 string/ReactClass type简而言之,babel在编译过程中会判断 JSX 组件的首字母,如果是小写,则当做原生的DOM标签解析,就编译成字符串。如果是大写,则认为是自定义组件,编译成对象。
三. 虚拟DOM, diff算法
虚拟DOM是什么
虚拟DOM 就是使用一个 原生的JavaScript对象来描述 一个DOM节点。
使用虚拟DOM表示如下:
React diff原理,如何从 O(n^3)变成 O(n)
其核心是基于两个简单的假设:
基于以上这两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。
React’s diff algorithm
生命周期(16版本之前和之后的)
16版本之前的生命周期
第一次渲染
props更新
state更新
组件卸载
componentWillUnmount
16版本之后的生命周期
第一次渲染
props或state更新
组件卸载
componentWillUnmount
五.React事件机制
React事件和原生事件有什么区别
preventDefault
;React 事件中为什么要绑定 this 或者 要用箭头函数, 他们有什么区别
回调函数是直接调用的,如果不手动绑定 this,获取到的 this为 undefined
六.fiber
render之前的生命周期,即将被废弃
componentWillMount
componentWillUpdate
componentWillReceiveProps
在16.x版本之前,每个生命周期在加载或更新过程中只会调用一次,因为新的fiber架构允许在 diff的时候不停的中断执行,所有render之前的声明周期可能会执行很多次。
fiber分为两部分
js是单线程的,如果当前在执行一个很耗时的任务,那么剩下的任务就要等当前任务执行完之后再执行。16.x版本之前,React的更新过程是同步的,当React决定要更新DOM时,从diff到更新DOM,一气呵成。这种就会有一个问题,更新的组件比较复杂并且多(层级深等)的时候,此时如果用户点击了页面某个按钮,可能会因为正在批量更新DOM还未进行完成,按钮无法响应的问题。
fiber架构第一个阶段是分片的,将一个任务成很多个小的任务去执行,每次只执行一个小的任务,然后去看一下有没有优先级更高的任务,如果有,则去执行优先级更好的任务,如果没有,接着再执行下一小段任务。
为什么第二个阶段,更新渲染DOM必须是同步的呢,这个也很好理解。你总不能渲染了一半的时候去干其他的事情吧。
七. mixin、HOC、render props、hooks
mixin
vue和react中都曾用过mixin(react目前已经抛弃)
mixin(混入)本质上就是将对象复制到另一个对象上。
mixin存在的几个问题:
HOC
HOC是React社区提出的新的方式用来取代mixin的。
高阶函数是函数式编程中一个基本的概念,它描述了一种这样的函数:接受函数作为输入,或是返回一个函数,比如 map, reduce等都是高阶函数。
高阶组件( higher-order component),类似于高阶组件接受一个组件作为参数,返回另一个组件。
HOC的优点为:
HOC的问题是:
Render Props
render props: 通过props接受一个返回react element 的函数,来动态决定自己要渲染的结果
React Router中就用到了 Render Props
它有哪些问题呢
使用 hooks
具体实现就是通过一个函数来封装跟状态有关的逻辑,将这些逻辑从组件中抽取出来。而这个函数中我们可以使用其他的Hooks,也可以单独进行测试,甚至将它贡献给社区。
hooks的引入就是为了解决上面提到的这么问题,因为 使用函数式组件,我们在开发组件的时候,可以当做平常写函数一样自由。
函数复用是比较容易的,直接传不同的参数就可以渲染不同的组件,复杂组件实现,我们完全可以多封装几个函数,每个函数只单纯的负责一件事。而且很多公用的代码逻辑和一些场景我们可以抽出来,封装成自定义hooks使用,比如 Umi Hooks库封装了很多共用的逻辑,比如 useSearch,封装了异步搜索场景的逻辑;比如 useVirtualList,就封装了虚拟列表的逻辑。
八. immber和immutable
九.受控组件和非受控组件区别
受控组件和非受控组件区别
十一. vue和React区别
相同点
不同点
文章推荐
The text was updated successfully, but these errors were encountered: