如何防止组件的从新渲染?
React 中最常见的问题之一是组件不必要地从新渲染。React 提供了两个办法,在这些状况下十分有用:
React.memo()
:这能够避免不必要地从新渲染函数组件PureComponent
:这能够避免不必要地从新渲染类组件
这两种办法都依赖于对传递给组件的props
的浅比拟,如果props
没有扭转,那么组件将不会从新渲染。尽管这两种工具都十分有用,然而浅比拟会带来额定的性能损失,因而如果使用不当,这两种办法都会对性能产生负面影响。
通过应用 React Profiler,能够在应用这些办法前后对性能进行测量,从而确保通过进行给定的更改来理论改良性能。
React 性能优化
- shouldCompoentUpdate
- pureComponent 自带shouldCompoentUpdate的浅比拟优化
- 联合Immutable.js达到最优
说说你用react有什么坑点?
1. JSX做表达式判断时候,须要强转为boolean类型
如果不应用!!b
进行强转数据类型,会在页面外面输入0
。
render() { const b = 0; return <div> { !!b && <div>这是一段文本</div> } </div>}
2. 尽量不要在 componentWillReviceProps
里应用 setState,如果肯定要应用,那么须要判断完结条件,不然会呈现有限重渲染,导致页面解体
3. 给组件增加ref时候,尽量不要应用匿名函数,因为当组件更新的时候,匿名函数会被当做新的prop解决,让ref属性承受到新函数的时候,react外部会先清空ref,也就是会以null为回调参数先执行一次ref这个props,而后在以该组件的实例执行一次ref,所以用匿名函数做ref的时候,有的时候去ref赋值后的属性会取到null
4. 遍历子节点的时候,不要用 index 作为组件的 key 进行传入
组件是什么?类是什么?类变编译成什么
- 组件指的是页面的一部分,实质就是一个类,最实质就是一个构造函数
- 类编译成构造函数
React 中 refs 的作用是什么
Refs
是React
提供给咱们的平安拜访DOM
元素或者某个组件实例的句柄- 能够为元素增加
ref
属性而后在回调函数中承受该元素在DOM
树中的句柄,该值会作为回调函数的第一个参数返回
在 Reducer文件里,对于返回的后果,要留神哪些问题?
在 Reducer文件里,对于返回的后果,必须要应用 Object.assign ( )来复制一份新的 state,否则页面不会跟着数据刷新。
return Object.assign({}, state, { type: action.type, shouldNotPaint: true,});
setState办法的第二个参数有什么用?应用它的目标是什么?
它是一个回调函数,当 setState办法执行完结并从新渲染该组件时调用它。在工作中,更好的形式是应用 React组件生命周期之——“存在期”的生命周期办法,而不是依赖这个回调函数。
export class App extends Component { constructor(props) { super(props); this.state = { username: "雨夜清荷", }; } render() { return <div> {this.state.username}</div>; } componentDidMount() { this.setstate( { username: "有课前端网", }, () => console.log("re-rendered success. ") ); }}
参考:前端react面试题具体解答
shouldComponentUpdate有什么用?为什么它很重要?
组件状态数据或者属性数据产生更新的时候,组件会进入存在期,视图会渲染更新。在生命周期办法 should ComponentUpdate中,容许抉择退出某些组件(和它们的子组件)的和解过程。
和解的最终目标是依据新的状态,以最无效的形式更新用户界面。如果咱们晓得用户界面的某一部分不会扭转,那么没有理由让 React弄清楚它是否应该更新渲染。通过在 shouldComponentUpdate办法中返回 false, React将让以后组件及其所有子组件放弃与以后组件状态雷同。
传入 setstate函数的第二个参数的作用是什么?
第二个参数是一个函数,该函数会在 setState函数调用实现并且组件开始重渲染时调用,能够用该函数来监听渲染是否实现。
this.setstate( { username: "有课前端网", }, () => console.log("re-rendered success. "));
setState 是同步的还是异步的
有时体现出同步,有时体现出异步
- setState 只有在 React 本身的合成事件和钩子函数中是异步的,在原生事件和 setTimeout 中都是同步的
- setState 的异步并不是说外部由异步代码实现,其实自身执行的过程和代码都是同步的,只是合成事件和钩子函数中没法立马拿到更新后的值,造成了所谓的异步。当然能够通过 setState 的第二个参数中的 callback 拿到更新后的后果
- setState 的批量更新优化也是建设在异步(合成事件、钩子函数)之上的,在原生事件和 setTimeout 中不会批量更新,在异步中如果对同一个值进行屡次 setState,setState 的批量更新策略会对其进行笼罩,去最初一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新
- 合成事件中是异步
- 钩子函数中的是异步
- 原生事件中是同步
- setTimeout中是同步
说说 React组件开发中对于作用域的常见问题。
在 EMAScript5语法标准中,对于作用域的常见问题如下。
(1)在map等办法的回调函数中,要绑定作用域this(通过bind办法)。
(2)父组件传递给子组件办法的作用域是父组件实例化对象,无奈扭转。
(3)组件事件回调函数办法的作用域是组件实例化对象(绑定父组件提供的办法就是父组件实例化对象),无奈扭转。
在 EMAScript6语法标准中,对于作用域的常见问题如下。
(1)当应用箭头函数作为map等办法的回调函数时,箭头函数的作用域是以后组件的实例化对象(即箭头函数的作用域是定义时的作用域),毋庸绑定作用域。
(2)事件回调函数要绑定组件作用域。
(3)父组件传递办法要绑定父组件作用域。
总之,在 EMAScript6语法标准中,组件办法的作用域是能够扭转的。
概述一下 React中的事件处理逻辑。
为了解决跨浏览器兼容性问题, React会将浏览器原生事件( Browser Native Event)封装为合成事件( Synthetic Event)并传入设置的事件处理程序中。
这里的合成事件提供了与原生事件雷同的接口,不过它们屏蔽了底层浏览器的细节差别,保障了行为的一致性。另外, React并没有间接将事件附着到子元素上,而是以繁多事件监听器的形式将所有的事件发送到顶层进行解决(基于事件委托原理)。
这样 React在更新DOM时就不须要思考如何解决附着在DOM上的事件监听器,最终达到优化性能的目标。
redux中间件
中间件提供第三方插件的模式,自定义拦挡action
->reducer
的过程。变为action
->middlewares
->reducer
。这种机制能够让咱们扭转数据流,实现如异步action
,action
过滤,日志输入,异样报告等性能
redux-logger
:提供日志输入redux-thunk
:解决异步操作redux-promise
:解决异步操作,actionCreator
的返回值是promise
为什么虚构dom会进步性能
虚构dom
相当于在js
和实在dom
两头加了一个缓存,利用dom diff
算法防止了没有必要的dom
操作,从而进步性能
具体实现步骤如下
- 用
JavaScript
对象构造示意 DOM 树的构造;而后用这个树构建一个真正的DOM
树,插到文档当中 - 当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记录两棵树差别
- 把2所记录的差别利用到步骤1所构建的真正的
DOM
树上,视图就更新
虚构DOM肯定会进步性能吗?
很多人认为虚构DOM肯定会进步性能,肯定会更快,其实这个说法有点全面,因为虚构DOM尽管会缩小DOM操作,但也无奈防止DOM操作
- 它的劣势是在于diff算法和批量解决策略,将所有的DOM操作收集起来,一次性去扭转实在的DOM,但在首次渲染上,虚构DOM会多了一层计算,耗费一些性能,所以有可能会比html渲染的要慢
- 留神,虚构DOM实际上是给咱们找了一条最短,最近的门路,并不是说比DOM操作的更快,而是门路最简略
在 ReactNative中,如何解决8081端口号被占用而提醒无法访问的问题?
在运行 react-native start时增加参数port 8082;在 package.json中批改“scripts”中的参数,增加端口号;批改我的项目下的 node\_modules \react-native\local- cli\server\server.js文件配置中的 default端口值。
组件更新有几种办法
- this.setState() 批改状态的时候 会更新组件
- this.forceUpdate() 强制更新
- 组件件render之后,子组件应用到父组件中状态,导致子组件的props属性产生扭转的时候 也会触发子组件的更新
当渲染一个列表时,何为 key?设置 key 的目标是什么
Keys 会有助于 React 辨认哪些 items
扭转了,被增加了或者被移除了。Keys 应该被赋予数组内的元素以赋予(DOM)元素一个稳固的标识,抉择一个 key 的最佳办法是应用一个字符串,该字符串能惟一地标识一个列表项。很多时候你会应用数据中的 IDs 作为 keys,当你没有稳固的 IDs 用于被渲染的 items
时,能够应用我的项目索引作为渲染项的 key,但这种形式并不举荐,如果 items
能够从新排序,就会导致 re-render
变慢。
React 高阶组件、Render props、hooks 有什么区别,为什么要一直迭代
这三者是目前react解决代码复用的次要形式:
- 高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 本身不是 React API 的一部分,它是一种基于 React 的组合个性而造成的设计模式。具体而言,高阶组件是参数为组件,返回值为新组件的函数。
- render props是指一种在 React 组件之间应用一个值为函数的 prop 共享代码的简略技术,更具体的说,render prop 是一个用于告知组件须要渲染什么内容的函数 prop。
- 通常,render props 和高阶组件只渲染一个子节点。让 Hook 来服务这个应用场景更加简略。这两种模式仍有用武之地,(例如,一个虚构滚动条组件或者会有一个 renderltem 属性,或是一个可见的容器组件或者会有它本人的 DOM 构造)。但在大部分场景下,Hook 足够了,并且可能帮忙缩小嵌套。
(1)HOC 官网解释∶
高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 本身不是 React API 的一部分,它是一种基于 React 的组合个性而造成的设计模式。
简言之,HOC是一种组件的设计模式,HOC承受一个组件和额定的参数(如果须要),返回一个新的组件。HOC 是纯函数,没有副作用。
// hoc的定义function withSubscription(WrappedComponent, selectData) { return class extends React.Component { constructor(props) { super(props); this.state = { data: selectData(DataSource, props) }; } // 一些通用的逻辑解决 render() { // ... 并应用新数据渲染被包装的组件! return <WrappedComponent data={this.state.data} {...this.props} />; } };// 应用const BlogPostWithSubscription = withSubscription(BlogPost, (DataSource, props) => DataSource.getBlogPost(props.id));
HOC的优缺点∶
- 长处∶ 逻辑服用、不影响被包裹组件的外部逻辑。
- 毛病∶ hoc传递给被包裹组件的props容易和被包裹后的组件重名,进而被笼罩
(2)Render props 官网解释∶
"render prop"是指一种在 React 组件之间应用一个值为函数的 prop 共享代码的简略技术
具备render prop 的组件承受一个返回React元素的函数,将render的渲染逻辑注入到组件外部。在这里,"render"的命名能够是任何其余无效的标识符。
// DataProvider组件外部的渲染逻辑如下class DataProvider extends React.Components { state = { name: 'Tom' } render() { return ( <div> <p>共享数据组件本人外部的渲染逻辑</p> { this.props.render(this.state) } </div> ); }}// 调用形式<DataProvider render={data => ( <h1>Hello {data.name}</h1>)}/>
由此能够看到,render props的优缺点也很显著∶
- 长处:数据共享、代码复用,将组件内的state作为props传递给调用者,将渲染逻辑交给调用者。
- 毛病:无奈在 return 语句外拜访数据、嵌套写法不够优雅
(3)Hooks 官网解释∶
Hook是 React 16.8 的新增个性。它能够让你在不编写 class 的状况下应用 state 以及其余的 React 个性。通过自定义hook,能够复用代码逻辑。
// 自定义一个获取订阅数据的hookfunction useSubscription() { const data = DataSource.getComments(); return [data];}// function CommentList(props) { const {data} = props; const [subData] = useSubscription(); ...}// 应用<CommentList data='hello' />
以上能够看出,hook解决了hoc的prop笼罩的问题,同时应用的形式解决了render props的嵌套天堂的问题。hook的长处如下∶
- 应用直观;
- 解决hoc的prop 重名问题;
- 解决render props 因共享数据 而呈现嵌套天堂的问题;
- 能在return之外应用数据的问题。
须要留神的是:hook只能在组件顶层应用,不可在分支语句中应用。、
vue 或者react 优化整体优化
- 虚构dom
为什么虚构 dom 会进步性能?(必考)
虚构 dom 相当于在 js 和实在 dom 两头加了一个缓存,利用 dom diff 算法防止了没有必要的 dom 操作,从而进步性能。
用 JavaScript 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记录两棵树差别把 2 所记录的差别利用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
如何通知 React 它应该编译生产环境版
通常状况下咱们会应用Webpack
的DefinePlugin
办法来将NODE_ENV
变量值设置为production
。编译版本中React
会疏忽propType
验证以及其余的告警信息,同时还会升高代码库的大小,React
应用了Uglify
插件来移除生产环境下不必要的正文等信息