1.1. 什么是组件?
前端开发中组件也称为UI组件,组件即将一段或几段完成各自功能的代码段封装为一个或几个独立的部分。UI组件包含了这样一个或几个具有各自功能的代码段,最终完成了用户界面的表示。React鼓励你为每一个关注点创造出一个独立的组件,比如:
<App> 代表整个应用 <Header> 代表头部 <DataGrid> 代表数据表格 <Footer> 代表底部
当然,以上组件内部还是可以细分,比如数据表格,由表头、行、分页条等等。React做开发其实就是为页面中的功能开发对应的组件,然后在把这些组件整合在一起就变成了一个完整的应用。
1.2. Hello组件
期望网页中输出 <h1>Hello</h1>
1.2.1创建组件
React创建组件只需要通过,React.createClass({ /* 组件定义信息 */ }),render方法代表渲染(展示)到页面的内容。
React采用模块化开发,所以每一个组件应该放在一个模块中(独立的js文件中)。
src/components/Hello.js
import React from 'react'; import ReactDOM from 'react-dom'; class Hello extends React.Component{ constructor(props){ super(props); } render(){ return <h1>hello ,world</h1> } } export default Hello;
1.2.2 使用组件
使用组件,首先先导入组件,然后就可以像标签一样使用。
//组件采用模块管理,所以我们使用组件需要导入
import Hello from './components/Hello';
ReactDOM.render(<Hello />, document.getElementById('app') );
1.2.3 动态数据展示
Hello组件目前只能显示某个固定的值,也就说显示的文本现在是写死在代码中。return <h1>Hello</h1>;
使用表达式{},可以动态的获取需要显示的值。使用组件的时候,把需要显示的文本传递给组件对象。
<Hello text=‘今天天气不错’ />
组件内部this.props代表所有属性对象,使用this.props.text获取具体某个属性值。 通过标签属性方式传入,组件内部使用this.props.propName获取属性值。
<body> <div id="example"> </div> <script type="text/babel"> class Hello extends React.Component{ constructor(props){ super(props); } render(){ return <h1>{this.props.hello}</h1> } } ReactDOM.render(<
Hello
hello="hello,world"/>,document.getElementById('example')) </script> </body>
1.2.4 子节点
使用一个自定义的组件的时候,就跟我们以前使用一个HTML标签的方式一模一样,可以通过属性传入数据给组件对象,此外,可以通过“子节点”的方式把内容传给组件对象,使用this.props.children获取。
比如:<Message name=’香菇’>快来吃我,我很蓝瘦</Message>
this.props.name 香菇
this.props.children 快来吃我,我很蓝瘦
<body> <div id="example"> </div> <script type="text/babel"> class Hello extends React.Component{ constructor(props){ super(props); } render(){ return <h1>{this.props.hello} -- {this.props.children}</h1> } } ReactDOM.render(<Hello hello="hello,world">child text</Hello>,document.getElementById('example')) </script> </body>
1.2.5 属性默认值
一个组件可能有很多的属性组件,有的属性不要求使用者必须设置值,但是又希望该属性拥有一个默认值。
es5中使用getDefaultProps 方法可以用来设置组件属性的默认值,getDefaultProps的返回值就是默认值。
es6中如下:
class Video extends React.Component { static defaultProps = { autoPlay: false, maxLoops: 10, } static propTypes = { autoPlay: React.PropTypes.bool.isRequired, maxLoops: React.PropTypes.number.isRequired, posterFrameSrc: React.PropTypes.string.isRequired, videoSrc: React.PropTypes.string.isRequired, } state = { loopsRemaining: this.props.maxLoops, } }
1.3 列表组件
1.3.1. 组件需求
期望网页根据一个数组生成一个列表。
<ul> <li>aaaa</li> <li>bbbb</li> <li>cccc</li> </ul>
1.3.2. 创建组件
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="example"> </div> <script type="text/babel"> class Hello extends React.Component{ constructor(props){ super(props); } render(){ console.log(this.props.datas); var data = this.props.datas.map((item,index)=>{return (<li>第{index},{item}</li>)}); return ( <ul> {data} </ul> ); } } ReactDOM.render(<Hello datas={["hello","world","!!!"]}/>,document.getElementById('example')) </script> </body> </html>
1.3.3. 列表问题
如果以上代码,没有意外会出现:
Each child in an array or iterator should have a unique "key" prop.
一个数组或迭代器中的每个子元素都应该有一个唯一的“key”键。
列表中React需要我们为的每个元素提供一个唯一的“key”标识符,使得React能够更智能的重用一个组件(因为DOM的创建是非常耗时的),还是销毁并重新创建一个组件,从而提高性能。
简单理解:key可以提高react的渲染性能。
1.4. 复合组件
React让我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。
1.4.1. 组件需求
输出网站名称和网址的组件。
主组件:(WebSite)
网站名称的组件;(Name)
网址地址组件;(Link)
<WebSite name=‘源代码’ src=’http://www.itsource.cn’ />
1.4.2. 组件代码
//显示网站名称组件
import React from 'react'; import ReactDOM from 'react-dom'; class Name extends React.Component{ constructor(props){ super(props); } render(){ return (<span>{this.props.name}</span>) } } export default Name;
//显示网站地址组件
import React from 'react'; import ReactDOM from 'react-dom'; class Link extends React.Component{ constructor(props){ super(props); } render(){ return (<a href={this.props.url}>{this.props.url}</a>); } }; export default Link;
//复合组件
import React from 'react'; import Name from './Name'; import Link from './Link'; class WebSite extends React.Component{ constructor(props){ super(props); } render(){ return ( <div> <Name name={this.props.name}/> <br/> <Link url={this.props.url}/> </div> ); } } export default WebSite;
1.4.3. 使用复合组件
index.js入口文件
import React from 'react'; import ReactDOM from 'react-dom'; import WebSite from './components/WebSite'; ReactDOM.render(<WebSite name="website name---name compnent" url="url - urlLink"/>,document.getElementById('example'))
运行结果:
1.4.4. 复合组件数据流
数据流:由父节点传递到子节点,如果顶层组件props改变了,React会向下传递。