React示例代码:
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
ReactDOM.render(<HelloMessage name="John" />, mountNode);
代码解析:
代码中实现了一个名为HelloMessage的组件,他接收一个name属性,可以在页面上展示出 Hello xxx
ReactDOM.render是用来将某个组件渲染到页面的某个DOM节点上
JSX:
上面这种在JavaScript中写类似HTML代码的语法被称之为JSX。可以理解我扩展版的JavaScript。这种语法在浏览器环境中是不能执行的,所以在代码加载到页面中之前,
需要通过工具将他转译为标准的JavaScript语法。
JSX语法示例:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
JavaScript语法示例:
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
HTML中的所有标签,在JSX中都是支持的,只有以下几点略微不同:
class属性变为className
tabindex属性变为tabIndex
for属性变为htmlFor
textarea的值需要通过value来指定
style属性的值接收一个对象,css的属性变为驼峰写法,如:backgroundColor
定义组件的几种方式:
1. 类继承
ES6为JavaScript增加了类和类继承的特性。子类会继承父类的 ‘基因’ (成员方法、属性),如果父类是一个组件,那么子类也是一个组件
React提供了Component 和 PureComponent 两个父类
创建组件示例:
import React,{Component} from 'react';
class HelloMessage extends Component{
render(){
return <div>Hello World</div>
}
}
概括:只要继承Component基类并且实现render方法即可,然后就可以把HelloMessage当成一个新的'HTML'标签使用
渲染到页面示例:
ReactDOM.render(<HelloMessage/>,document.querySelector('#root'))
页面展示:
2. 函数式组件
以函数的形式来定义一个组件
创建组件示例:
import React from 'react';
function HelloMessage(){
return <div>Hello world</div>
}
//或者
const HelloMessage=()=><div>Hello World</div>
简要概括:实际上就是实现了类继承方式中的render方法
渲染到页面示例:
ReactDOM.render(<HelloMessage/>,document.querySelector('#root'))
页面展示:
类继承 vs 函数式组件
类继承虽然写起来繁琐,但是拥有更多的特性:
内部状态:state
生命周期函数
函数式组件虽然没有state和生命周期函数等特性,但是有简洁的书写方式,更好的性能
注意: 不管哪种方式,组件的首字母必须为大写
属性
如果把组件理解为一个函数,那么属性就是函数的参数,函数的返回值就是呈现到页面上的视图
属性必须是只读的,非常重要,必须遵守
1. 默认属性:
通常情况下,我们需要为组件的属性设为默认值,就像HTML标签的属性也有默认值一样
如果需求是当不传入name属性时,默认展示 HelloWorld,也就是name的默认值是World
示例:
<div>Hello {this.props.name}||world</div>
但是属性可能会使Object,或者函数,所以React提供了相应的机制可以设置组件属性的默认值
通过组件的静态字段 defaultProps 来设置组件属性的默认值
示例:
import React,{Component} from 'react';
class HelloMessage extends Component{
render(){
return <div>Hello {this.props.name}</div>
}
}
HelloMessage.defaultProps={
name:'World'
}
2. 属性的类型及校验
例如 HelloMessage 组件中,我们期望 name 属性只能是字符串类型,但是给的是Object,是没有办法正确展示的,为了在开发过程中尽快的发现这类问题
React为组件添加了类型检查机制,需要给组件设置静态字段 propTypes 来设置组件各个属性的类型检查器
示例:
import React,{Component} from 'react';
import PropTypes from 'propTypes';
class HelloMessage extends Component{
render(){
return <div>Hello {this.props.name}</div>
}
}
HelloMessage.defaultProps={
name:'World'
}
HelloMessage.propTypes={
name:PropTypes.string
}
这样在开发过程中 React 就能校验组件接收到的属性值是否符合指定的类型,如果校验不通过就会抛出警告
React 只会在开发模式下进行属性类型检查,当代码进行生产发布后,为了减少额外的性能,类型检查将会被忽略
以下是 React 提供的可用的数据类型检查器:
PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
PropTypes.symbol
PropTypes.element 元素,实际就是JSX表达式,一个JSX表达式会生成一个JS对象,在React中被称为元素(Element)
PropTypes.node所有可用被渲染的数据类型,包括:数值,字符串,元素或者这些类型的数组
PropTypes.instanceOf(Message) 某个类的实例
PropTypes.oneOf(['News','Photos'])枚举,属性值必须为其中的某一个值
PropTypes.oneOfType([PropTypes.String,PropTypes.number])类型枚举,属性必须为其中某个类型
PropTypes.arrayOf(PropTypes.number) 属性为一个数组,且数组中的元素必须符合指定类型
PropTypes.objectOf(PropTypes.number) 属性为一个对象,且对象中的各个字段的值必须符合指定的类型
PropTypes.any 任何类型
如果想知道某些属性为必须类型,可以链式调用其 isRequired 来标识某个属性对于当前组件来说是必需的。如果再使用组件是未指定会抛出警告
也可以通过设置函数自定义属性验证器,如果验证不通过则需要返回一个Error实例
示例:
function(props,propName,componentName){
if(!/matchme/.test(props[propName])){
return new Error(
'Invalid prop `'+propName +'`supplied to'+'`'+componentName+'`.Validation failed
)
}
}
3. 设置组件的属性值
属性的值可以使用一堆大括号 { } 来包围,其中可以指定任意的JavaScript表达式
示例:
return (
<User
name='Tom' //字符串
age={18} //数值
isActivated={true} //布尔值
interests={['yellow','red']} //数组
address={{city:'Beijing',road:'BeiSiHuanDongLu'}} //对象
/>
)
4. 展开操作符
可以使用 ... 展开操作符将一个对象的所有字段展开,依次作为属性传递给组件,所以上面的代码等价于
示例:
5. 值为 true 的属性的简写
const userInfo={ name='Tom' //字符串 age={18} //数值 isActivated={true} //布尔值 interests={['yellow','red']} //数组 address={{city:'Beijing',road:'BeiSiHuanDongLu'}} //对象 } return <User {...userInfo}>
如果属性类型为布尔值,且当前属性值为 true 可以只写属性名
示例:
<input disabled type='text'/> //禁用该输入框
6. children 属性
用户自定义的组件内可以通过this.props.chidren来获取一个特殊的属性。该属性与其它属性的区别就是传递方式不同
children 属性的值是指一对闭合的JSX标签中间的内容
示例:
<UserList>
<User name='Tom'/>
<User name='Lucy'>
<UserList>
可以通过 this.props.children ,在 UserList 内部来获取下面这个JSX片段:
<User name='Tom'/>
<User name='Lucy'>
获取到的实际上是一个包含两个 User 元素对象的数组
文件借鉴: http://react-china.org/t/react-react/15548