1. 使用纯函数且采用方法调用的形式可以提高性能
    性能提高不明显的方式:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    # app.js
    import React, { Component, PropTypes } from 'react';

    import styles from '../css/app.css'
    import CusImg from './cusimg'

    export default class App extends Component {
    constructor(props) {
    super(props);

    }

    render() {
    return (
    <div className={styles.haha}>
    <CusImg
    style={styles.root}
    textStyle={styles.textStyle}
    imgurl={require('../imgs/qcord.png')}
    text="二维码" />

    </div>
    );
    }
    }

性能提高明显的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# app.js

render() {
return (
<div className={styles.haha}>
{CusImg({
style:styles.root ,
textStyle:styles.textStyle,
imgurl:require('../imgs/qcord.png'),
text:"二维码"
})}
</div>
);
}
  1. 不要在render的组件上绑定带参的函数
    1
    <CommentItem likeComment={() => this.likeComment(user.id)} />

应该这样

1
<CommentItem likeComment={this.likeComment} userID={user.id} />

这个问题会导致每次父组件render方法被调用时,一个新的函数被创建,已将其传入likeComment。这会有一个改变每个子组件props的副作用,它将会造成他们全部重新渲染,即使数据本身没有发生变化。

  1. 不要在render方法里派生数据
1
2
3
4
5
render() {
const { posts } = this.props
const topTen = posts.sort((a, b) => b.likes - a.likes).slice(0, 9)
return //...
}

每次组件重新渲染时topTen都将有一个新的引用,即使posts没有改变并且派生数据也是相同的。这将造成列表不必要的重新渲染。
你可以这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
componentWillMount() {
this.setTopTenPosts(this.props.posts)
}
componentWillReceiveProps(nextProps) {
if (this.props.posts !== nextProps.posts) {
this.setTopTenPosts(nextProps)
}
}
setTopTenPosts(posts) {
this.setState({
topTen: posts.sort((a, b) => b.likes - a.likes).slice(0, 9)
})
}
  1. PureComponent使用浅比较判断组件是否需要重绘,浅比较是比较指针的异同.只要在对象上修改属性,对象指针不变,则不会渲染。为了避免出现这些问题,推荐使用immutable.js。immutable.js会在每次对原对象进行添加,删除,修改使返回新的对象实例。任何对数据的修改都会导致数据指针的变化。

  2. 数组问题

    1
    2
    3
      {this.props.items.map(i =>
    <Cell data={i} options={this.props.options || []} />
    )}

    []每次返回的都是新的指针,会引起重绘,应该这样:

    1
    2
    3
    4
    const default = [];
    {this.props.items.map(i =>
    <Cell data={i} options={this.props.options || default} />
    )}
    1. react数据流都是自顶向下单向流动的,从父组件到子组件。

    2. 无状态组件如何避免没有意义的重新渲染??

    3. react中使用原生的事件绑定,一定要记得卸载,否则容易内存泄漏,而使用react原生的事件机制不需要,因为已经帮我们处理了。

    4. 不要将原生事件和react事件混用。React的e.stopPropagation只能阻止react的。原生中可以阻止react冒泡,react不可以阻止原生的冒泡。

    5. 使用classnames 处理多个className情况,比较灵活的决定需要使用哪个样式。

    6. 父组件-子组件通信=>props

    7. 子组件-父组件通信=> 利用回调、利用自定义事件机制

    8. 使用context跨级组件实现父子通信-最好是真正的全局信息,才使用context比如主题等

    9. 没有嵌套关系的组件通信可以通过事件机制

    10. 高阶函数:指的接收一个函数作为参数、或者输出一个函数的函数。比如map\reduce就是告诫函数

    11. 高阶组件:以一个react组件作为参数,输出一个新的react组件,可以对render做劫持、也可以对state和props做控制。

    12. 高阶组件将对state的操作从组件中提取到高阶组件中,增加复用性。

    13. 反向继承:

      1
      2
      3
      4
      5
      6
      class MyContainer - (WrappedComponent) =>
      classs extends WrappedComponent {
      render() {
      return super.render();
      }
      }
    14. 纯函数:(1)固定输入则固定输出(2)没额外的依赖(3)不会产生副作用。