本文从属于React入门与最佳实践中的React组件基础react
前文介绍的组件的定义方式主要是声明式组件,其与传统的jQuery中以DOM操做为核心的命令式组件生成相比具备更大的灵活性与可组合性。而实际上随着应用复杂度与所须要的组件数目的持续增长,咱们所须要的组件也会被划分为不少的类型。从组件组合的角度或者所谓动态组件的角度来看,常见的便是HOC模式,即将某个组件做为另外一个组件的Props或者子组件从而封装出高阶组件。还有另外一种偏向函数式的模式便是构造出函数式组件,就好像Arrow Function同样,对于无状态的简单组件,使用函数式组件的方式声明,会使得代码的可读性更好,而且减小冗余代码的数目。在React自己对于界面的抽象能够用View = f(props)
,即纯粹的界面的渲染函数能够近似看作纯函数。函数式组件与基于Class声明的组件相比,其具备如下特性:git
不须要声明类,能够避免大量的譬如extends或者constructor这样的代码github
不须要显示声明this关键字,在ES6的类声明中每每须要将函数的this关键字绑定到当前做用域,而由于函数式声明的特性,咱们不须要再强制绑定:web
onClick={this.sayHi.bind(this)}>Say Hi</a> onClick={sayHi}>Say Hi</a>
贯彻最佳实践,在React组件复用与组合中咱们会提到,应当避免在底层的展现性组件中混入对于状态的管理,而应该将状态托管于某个高阶组件或者其余的状态容器中。利用函数式声明组件能够完全保证不会在组件中进行状态操做。编程
易于理解与测试frontend
更佳的性能表现:由于函数式组件中并不须要进行生命周期的管理与状态管理,所以React并不须要进行某些特定的检查或者内存分配,从而保证了更好地性能表现。函数式编程
最后,经过下图的对比,能够看出函数式组件声明方法的简洁性:函数
这里咱们定义一个简单的Text组件:性能
class Text extends React.Component { render() { return <p>{this.props.children}</p>; } } React.render(<Text>Hello World</Text>, document.body);
上面定义的Text组件能够看作典型的Pure Components,或者说是Dummy Components,即好像函数式编程中的纯函数同样,输出彻底由输入的Props决定,而且不会产生任何的反作用。这种类型的组件会在咱们的应用中占据很大的份额,而在React 0.14以后也容许咱们以相似于定义函数的方式来定义这种无状态组件,以下所示:测试
const Text = (props) => <p>{props.children}</p>; // ReactDOM is part of the introduction of React 0.14 ReactDOM.render( <Text>Hello World</Text>, document.querySelector('#root') );
这种模式主要是鼓励在大型项目中尽量地以简单的写法来分割本来庞大的组件,而将来React也会面向这种无状态的组件在譬如避免无心义的检查或者内存分配领域进行一些专门的优化。这种无状态函数式组件的写法也是支持设置默认的Props类型与值的:
const Text = ({ children }) => <p>{children}</p> Text.propTypes = { children: React.PropTypes.string }; Text.defaultProps = { children: 'Hello World!' };
咱们也能够利用ES6默认函数参数的方式来设置默认值:
const Text = ({ children = 'Hello World!' }) => <p>{children}</p>
另外,在无状态的组件函数中,咱们也是能够访问Context的:
const Text = (props, context) => <p style={context}>props.children</p>; Text.contextTypes = { fontFamily: React.PropTypes.string }; class App extends React.Component { static childContextTypes = { fontFamily: React.PropTypes.string } getChildContext() { return { fontFamily: 'Helvetica Neue' }; } render() { return <Text>Hello World</Text>; } }