网站优化入门,舆情分析报告怎么写,阿里巴巴1688采购平台官网,长春到四平1、setState 是异步还是同步#xff1f; 合成事件中是异步 钩子函数中的是异步 原生事件中是同步 setTimeout中是同步 相关链接#xff1a;你真的理解setState吗#xff1f;#xff1a;
2、聊聊 react16.4 的生命周期 图片 相关连接#xff1a;React 生命周期 我对 Reac…1、setState 是异步还是同步 合成事件中是异步 钩子函数中的是异步 原生事件中是同步 setTimeout中是同步 相关链接你真的理解setState吗
2、聊聊 react16.4 的生命周期 图片 相关连接React 生命周期 我对 React v16.4 生命周期的理解
3、useEffect(fn, []) 和 componentDidMount 有什么差异 useEffect 会捕获 props 和 state。所以即便在回调函数里你拿到的还是初始的 props 和 state。如果想得到“最新”的值可以使用ref。
4、hooks 为什么不能放在条件判断里 以 setState 为例在 react 内部每个组件(Fiber)的 hooks 都是以链表的形式存在 memoizeState 属性中
图片 update 阶段每次调用 setState链表就会执行 next 向后移动一步。如果将 setState 写在条件判断中假设条件判断不成立没有执行里面的 setState 方法会导致接下来所有的 setState 的取值出现偏移从而导致异常发生。
参考链接烤透 React Hook
5、fiber 是什么 React Fiber 是一种基于浏览器的单线程调度算法。
React Fiber 用类似 requestIdleCallback 的机制来做异步 diff。但是之前数据结构不支持这样的实现异步 diff于是 React 实现了一个类似链表的数据结构将原来的 递归diff 变成了现在的 遍历diff这样就能做到异步可更新了。
图片 相关链接React Fiber 是什么
6、聊一聊 diff 算法 传统 diff 算法的时间复杂度是 O(n^3)这在前端 render 中是不可接受的。为了降低时间复杂度react 的 diff 算法做了一些妥协放弃了最优解最终将时间复杂度降低到了 O(n)。
那么 react diff 算法做了哪些妥协呢参考如下
1、tree diff只对比同一层的 dom 节点忽略 dom 节点的跨层级移动
如下图react 只会对相同颜色方框内的 DOM 节点进行比较即同一个父节点下的所有子节点。当发现节点不存在时则该节点及其子节点会被完全删除掉不会用于进一步的比较。
这样只需要对树进行一次遍历便能完成整个 DOM 树的比较。
图片
这就意味着如果 dom 节点发生了跨层级移动react 会删除旧的节点生成新的节点而不会复用。
2、component diff如果不是同一类型的组件会删除旧的组件创建新的组件
图片
3、element diff对于同一层级的一组子节点需要通过唯一 id 进行来区分
如果没有 id 来进行区分一旦有插入动作会导致插入位置之后的列表全部重新渲染。
这也是为什么渲染列表时为什么要使用唯一的 key。
7、调用 setState 之后发生了什么 在 setState 的时候React 会为当前节点创建一个 updateQueue 的更新列队。 然后会触发 reconciliation 过程在这个过程中会使用名为 Fiber 的调度算法开始生成新的 Fiber 树 Fiber 算法的最大特点是可以做到异步可中断的执行。 然后 React Scheduler 会根据优先级高低先执行优先级高的节点具体是执行 doWork 方法。 在 doWork 方法中React 会执行一遍 updateQueue 中的方法以获得新的节点。然后对比新旧节点为老节点打上 更新、插入、替换 等 Tag。 当前节点 doWork 完成后会执行 performUnitOfWork 方法获得新节点然后再重复上面的过程。 当所有节点都 doWork 完成后会触发 commitRoot 方法React 进入 commit 阶段。 在 commit 阶段中React 会根据前面为各个节点打的 Tag一次性更新整个 dom 元素。 8、为什么虚拟dom 会提高性能? 虚拟dom 相当于在 JS 和真实 dom 中间加了一个缓存利用 diff 算法避免了没有必要的 dom 操作从而提高性能。
9、错误边界是什么它有什么用 在 React 中如果任何一个组件发生错误它将破坏整个组件树导致整页白屏。这时候我们可以用错误边界优雅地降级处理这些错误。
例如下面封装的组件
class ErrorBoundary extends React.ComponentIProps, IState {constructor(props: IProps) {super(props);this.state { hasError: false };}static getDerivedStateFromError() {// 更新 state 使下一次渲染能够显示降级后的 UIreturn { hasError: true };}componentDidCatch(error, errorInfo) {// 可以将错误日志上报给服务器console.log(组件奔溃 Error, error);console.log(组件奔溃 Info, errorInfo);}render() {if (this.state.hasError) {// 你可以自定义降级后的 UI 并渲染return this.props.content;}return this.props.children;}
}10、什么是 Portals Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。
ReactDOM.createPortal(child, container)11、React 组件间有那些通信方式? 父组件向子组件通信 1、 通过 props 传递
子组件向父组件通信 1、 主动调用通过 props 传过来的方法并将想要传递的信息作为参数传递到父组件的作用域中
跨层级通信 1、 使用 react 自带的 Context 进行通信createContext 创建上下文 useContext 使用上下文。
参考下面代码
import React, { createContext, useContext } from react;const themes {light: {foreground: #000000,background: #eeeeee},dark: {foreground: #ffffff,background: #222222}
};const ThemeContext createContext(themes.light);function App() {return (ThemeContext.Provider value{themes.dark}Toolbar //ThemeContext.Provider);
}function Toolbar() {return (divThemedButton //div);
}function ThemedButton() {const theme useContext(ThemeContext);return (button style{{ background: theme.background, color: theme.foreground }}I am styled by theme context!/button);
}export default App;2、使用 Redux 或者 Mobx 等状态管理库
3、使用订阅发布模式
12、React 父组件如何调用子组件中的方法 1、如果是在方法组件中调用子组件 react16.8可以使用 useRef 和 useImperativeHandle:
const { forwardRef, useRef, useImperativeHandle } React;const Child forwardRef((props, ref) {useImperativeHandle(ref, () ({getAlert() {alert(getAlert from Child);}}));return h1Hi/h1;
});const Parent () {const childRef useRef();return (divChild ref{childRef} /button onClick{() childRef.current.getAlert()}Click/button/div);
};2、如果是在类组件中调用子组件 react16.4可以使用 createRef:
const { Component } React;class Parent extends Component {constructor(props) {super(props);this.child React.createRef();}onClick () {this.child.current.getAlert();};render() {return (divChild ref{this.child} /button onClick{this.onClick}Click/button/div);}
}class Child extends Component {getAlert() {alert(getAlert from Child);}render() {return h1Hello/h1;}
}13、React有哪些优化性能的手段? 类组件中的优化手段 1、使用纯组件 PureComponent 作为基类。
2、使用 React.memo 高阶函数包装组件。
3、使用 shouldComponentUpdate 生命周期函数来自定义渲染逻辑。
方法组件中的优化手段 1、使用 useMemo。
2、使用 useCallBack。
其他方式 1、在列表需要频繁变动时使用唯一 id 作为 key而不是数组下标。
2、必要时通过改变 CSS 样式隐藏显示组件而不是通过条件判断显示隐藏组件。
3、使用 Suspense 和 lazy 进行懒加载例如
import React, { lazy, Suspense } from react;export default class CallingLazyComponents extends React.Component {render() {var ComponentToLazyLoad null;if (this.props.name Mayank) {ComponentToLazyLoad lazy(() import(./mayankComponent));} else if (this.props.name Anshul) {ComponentToLazyLoad lazy(() import(./anshulComponent));}return (divh1This is the Base User: {this.state.name}/h1Suspense fallback{divLoading.../div}ComponentToLazyLoad //Suspense/div)}
}Suspense 用法可以参考官方文档
相关阅读21个React性能优化技巧
14、为什么 React 元素有一个 $$typeof 属性
目的是为了防止 XSS 攻击。因为 Synbol 无法被序列化所以 React 可以通过有没有 $$typeof 属性来断出当前的 element 对象是从数据库来的还是自己生成的。
如果没有 $$typeof 这个属性react 会拒绝处理该元素。
在 React 的古老版本中下面的写法会出现 XSS 攻击
// 服务端允许用户存储 JSON
let expectedTextButGotJSON {type: div,props: {dangerouslySetInnerHTML: {__html: /* 把你想的搁着 */},},// ...
};
let message { text: expectedTextButGotJSON };// React 0.13 中有风险
p{message.text}
/p15、React 如何区分 Class组件 和 Function组件 一般的方式是借助 typeof 和 Function.prototype.toString 来判断当前是不是 class如下
function isClass(func) {return typeof func function /^class\s/.test(Function.prototype.toString.call(func));
}但是这个方式有它的局限性因为如果用了 babel 等转换工具将 class 写法全部转为 function 写法上面的判断就会失效。
React 区分 Class组件 和 Function组件的方式很巧妙由于所有的类组件都要继承 React.Component所以只要判断原型链上是否有 React.Component 就可以了
AComponent.prototype instanceof React.Component16、HTML 和 React 事件处理有什么区别? 在 HTML 中事件名必须小写
button onclickactivateLasers()而在 React 中需要遵循驼峰写法
button onClick{activateLasers}在 HTML 中可以返回 false 以阻止默认的行为
a href# onclickconsole.log(The link was clicked.); return false; /而在 React 中必须地明确地调用 preventDefault()
function handleClick(event) {event.preventDefault()console.log(The link was clicked.)
}17、什么是 suspense 组件? Suspense 让组件“等待”某个异步操作直到该异步操作结束即可渲染。在下面例子中两个组件都会等待异步 API 的返回值
const resource fetchProfileData();function ProfilePage() {return (Suspense fallback{h1Loading profile.../h1}ProfileDetails /Suspense fallback{h1Loading posts.../h1}ProfileTimeline //Suspense/Suspense);
}function ProfileDetails() {// 尝试读取用户信息尽管该数据可能尚未加载const user resource.user.read();return h1{user.name}/h1;
}function ProfileTimeline() {// 尝试读取博文信息尽管该部分数据可能尚未加载const posts resource.posts.read();return (ul{posts.map(post (li key{post.id}{post.text}/li))}/ul);
}Suspense 也可以用于懒加载参考下面的代码
const OtherComponent React.lazy(() import(./OtherComponent));function MyComponent() {return (divSuspense fallback{divLoading.../div}OtherComponent //Suspense/div);
}18、为什么 JSX 中的组件名要以大写字母开头 因为 React 要知道当前渲染的是组件还是 HTML 元素。
19、redux 是什么 Redux 是一个为 JavaScript 应用设计的可预测的状态容器。
它解决了如下问题
跨层级组件之间的数据传递变得很容易 所有对状态的改变都需要 dispatch使得整个数据的改变可追踪方便排查问题。 但是它也有缺点
概念偏多理解起来不容易 样板代码太多 20、react-redux 的实现原理 通过 redux 和 react context 配合使用并借助高阶函数实现了 react-redux。
参考链接React.js 小书
21、reudx 和 mobx 的区别 得益于 Mobx 的 observable使用 mobx 可以做到精准更新对应的 Redux 是用 dispath 进行广播通过Provider 和 connect 来比对前后差别控制更新粒度
相关阅读Redux or MobX: An attempt to dissolve the Confusion
22、redux 异步中间件有什么什么作用? 假如有这样一个需求请求数据前要向 Store dispatch 一个 loading 状态并带上一些信息请求结束后再向Store dispatch 一个 loaded 状态
一些同学可能会这样做
function App() {const onClick () {dispatch({ type: LOADING, message: data is loading })fetch(dataurl).then(() {dispatch({ type: LOADED })});}return (divbutton onClick{onClick}click/button/div);
}但是如果有非常多的地方用到这块逻辑那应该怎么办
聪明的同学会想到可以将 onClick 里的逻辑抽象出来复用如下
function fetchData(message: string) {return (dispatch) {dispatch({ type: LOADING, message })setTimeout(() {dispatch({ type: LOADED })}, 1000)}
}function App() {const onClick () {fetchData(data is loading)(dispatch)}return (divbutton onClick{onClick}click/button/div);
}很好但是 fetchData(‘data is loading’)(dispatch) 这种写法有点奇怪会增加开发者的心智负担。
于是可以借助 rudux 相关的异步中间件以 rudux-chunk 为例将写法改为如下
function fetchData(message: string) {return (dispatch) {dispatch({ type: LOADING, message })setTimeout(() {dispatch({ type: LOADED })}, 1000)}
}function App() {const onClick () {
- fetchData(data is loading)(dispatch)dispatch(fetchData(data is loading))}return (divbutton onClick{onClick}click/button/div);
}这样就更符合认知一些了redux 异步中间件没有什么奥秘主要做的就是这样的事情。
相关阅读Why do we need middleware for async flow in Redux?
23、redux 有哪些异步中间件 1、redux-thunk
源代码简短优雅上手简单
2、redux-saga
借助 JS 的 generator 来处理异步避免了回调的问题
3、redux-observable
借助了 RxJS 流的思想以及其各种强大的操作符来处理异步问题 文章转载自: http://www.morning.gnfkl.cn.gov.cn.gnfkl.cn http://www.morning.rbmnq.cn.gov.cn.rbmnq.cn http://www.morning.srrrz.cn.gov.cn.srrrz.cn http://www.morning.ntnml.cn.gov.cn.ntnml.cn http://www.morning.fglzk.cn.gov.cn.fglzk.cn http://www.morning.bwttj.cn.gov.cn.bwttj.cn http://www.morning.rttxx.cn.gov.cn.rttxx.cn http://www.morning.sdamsm.com.gov.cn.sdamsm.com http://www.morning.mprtj.cn.gov.cn.mprtj.cn http://www.morning.xgchm.cn.gov.cn.xgchm.cn http://www.morning.lwxsy.cn.gov.cn.lwxsy.cn http://www.morning.ccjhr.cn.gov.cn.ccjhr.cn http://www.morning.smj78.cn.gov.cn.smj78.cn http://www.morning.fzlk.cn.gov.cn.fzlk.cn http://www.morning.lhzqn.cn.gov.cn.lhzqn.cn http://www.morning.dkqbc.cn.gov.cn.dkqbc.cn http://www.morning.lhptg.cn.gov.cn.lhptg.cn http://www.morning.cbqqz.cn.gov.cn.cbqqz.cn http://www.morning.rlksq.cn.gov.cn.rlksq.cn http://www.morning.gwmjy.cn.gov.cn.gwmjy.cn http://www.morning.cjsrg.cn.gov.cn.cjsrg.cn http://www.morning.zrgx.cn.gov.cn.zrgx.cn http://www.morning.gfhng.cn.gov.cn.gfhng.cn http://www.morning.qbnfc.cn.gov.cn.qbnfc.cn http://www.morning.ywpcs.cn.gov.cn.ywpcs.cn http://www.morning.rbnnq.cn.gov.cn.rbnnq.cn http://www.morning.hhpbj.cn.gov.cn.hhpbj.cn http://www.morning.ylpl.cn.gov.cn.ylpl.cn http://www.morning.ityi666.cn.gov.cn.ityi666.cn http://www.morning.fwllb.cn.gov.cn.fwllb.cn http://www.morning.yqsr.cn.gov.cn.yqsr.cn http://www.morning.rbhcx.cn.gov.cn.rbhcx.cn http://www.morning.jjsxh.cn.gov.cn.jjsxh.cn http://www.morning.cyyhy.cn.gov.cn.cyyhy.cn http://www.morning.tkfnp.cn.gov.cn.tkfnp.cn http://www.morning.jxzfg.cn.gov.cn.jxzfg.cn http://www.morning.nwrzf.cn.gov.cn.nwrzf.cn http://www.morning.ctqlq.cn.gov.cn.ctqlq.cn http://www.morning.slnz.cn.gov.cn.slnz.cn http://www.morning.yxbrn.cn.gov.cn.yxbrn.cn http://www.morning.ctrkh.cn.gov.cn.ctrkh.cn http://www.morning.nrcbx.cn.gov.cn.nrcbx.cn http://www.morning.chtnr.cn.gov.cn.chtnr.cn http://www.morning.nzfyx.cn.gov.cn.nzfyx.cn http://www.morning.ghpld.cn.gov.cn.ghpld.cn http://www.morning.btqqh.cn.gov.cn.btqqh.cn http://www.morning.rzrbw.cn.gov.cn.rzrbw.cn http://www.morning.lrjtx.cn.gov.cn.lrjtx.cn http://www.morning.rrdch.cn.gov.cn.rrdch.cn http://www.morning.jrtjc.cn.gov.cn.jrtjc.cn http://www.morning.sxlrg.cn.gov.cn.sxlrg.cn http://www.morning.znqmh.cn.gov.cn.znqmh.cn http://www.morning.smszt.com.gov.cn.smszt.com http://www.morning.trsfm.cn.gov.cn.trsfm.cn http://www.morning.jfbgn.cn.gov.cn.jfbgn.cn http://www.morning.kngx.cn.gov.cn.kngx.cn http://www.morning.rfljb.cn.gov.cn.rfljb.cn http://www.morning.pwdgy.cn.gov.cn.pwdgy.cn http://www.morning.dbphz.cn.gov.cn.dbphz.cn http://www.morning.yrmpr.cn.gov.cn.yrmpr.cn http://www.morning.buyid.com.cn.gov.cn.buyid.com.cn http://www.morning.yjdql.cn.gov.cn.yjdql.cn http://www.morning.brscd.cn.gov.cn.brscd.cn http://www.morning.srbmc.cn.gov.cn.srbmc.cn http://www.morning.gwgjl.cn.gov.cn.gwgjl.cn http://www.morning.jnvivi.com.gov.cn.jnvivi.com http://www.morning.zpkfb.cn.gov.cn.zpkfb.cn http://www.morning.nkiqixr.cn.gov.cn.nkiqixr.cn http://www.morning.mprky.cn.gov.cn.mprky.cn http://www.morning.zynjt.cn.gov.cn.zynjt.cn http://www.morning.seoqun.com.gov.cn.seoqun.com http://www.morning.kzrbd.cn.gov.cn.kzrbd.cn http://www.morning.fbfnk.cn.gov.cn.fbfnk.cn http://www.morning.dfkmz.cn.gov.cn.dfkmz.cn http://www.morning.hmtft.cn.gov.cn.hmtft.cn http://www.morning.lmknf.cn.gov.cn.lmknf.cn http://www.morning.gbqgr.cn.gov.cn.gbqgr.cn http://www.morning.bygyd.cn.gov.cn.bygyd.cn http://www.morning.qcfcz.cn.gov.cn.qcfcz.cn http://www.morning.xgcwm.cn.gov.cn.xgcwm.cn