如何防止组件的从新渲染?

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 的作用是什么

  • RefsReact 提供给咱们的平安拜访 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 是同步的还是异步的

有时体现出同步,有时体现出异步

  1. setState 只有在 React 本身的合成事件和钩子函数中是异步的,在原生事件和 setTimeout 中都是同步的
  2. setState 的异步并不是说外部由异步代码实现,其实自身执行的过程和代码都是同步的,只是合成事件和钩子函数中没法立马拿到更新后的值,造成了所谓的异步。当然能够通过 setState 的第二个参数中的 callback 拿到更新后的后果
  3. setState 的批量更新优化也是建设在异步(合成事件、钩子函数)之上的,在原生事件和 setTimeout 中不会批量更新,在异步中如果对同一个值进行屡次 setState,setState 的批量更新策略会对其进行笼罩,去最初一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新
  4. 合成事件中是异步
  5. 钩子函数中的是异步
  6. 原生事件中是同步
  7. 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。这种机制能够让咱们扭转数据流,实现如异步actionaction 过滤,日志输入,异样报告等性能
  • 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 优化整体优化

  1. 虚构dom

为什么虚构 dom 会进步性能?(必考)

虚构 dom 相当于在 js 和实在 dom 两头加了一个缓存,利用 dom diff 算法防止了没有必要的 dom 操作,从而进步性能。

用 JavaScript 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记录两棵树差别把 2 所记录的差别利用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。

如何通知 React 它应该编译生产环境版

通常状况下咱们会应用 WebpackDefinePlugin 办法来将 NODE_ENV 变量值设置为 production。编译版本中 React会疏忽 propType 验证以及其余的告警信息,同时还会升高代码库的大小,React 应用了 Uglify 插件来移除生产环境下不必要的正文等信息