什么时候用props?
当你的组件需要接收一个数据时使用props进行接收
怎么用props?
啥也不说,先撸代码
<script type="text/babel">
/**
* 需求:自定义用来显示一个人员信息的组件
* 1. 姓名必须指定
* 2. 如果性别没有指定,默认为男
* 3. 如果年龄没有指定,默认为18
*/
//创建组件
function Person(props) { //props是一个对象,实际上就是传过来的值的集合
let {name, age, sex} = props;
return (
<ul>
<li>姓名:{name}</li>
<li>年龄:{age}</li>
<li>性别:{sex}</li>
</ul>
)
}
//渲染组建标签
const person1 = {
name: 'Tom',
age: 23,
sex: '女'
};
//ES6对象的解构复制
ReactDOM.render(<Person {...person1}/>, document.getElementById('test'));
</script>
在上面的代码中,我们定义了一个Person无状态组件,运用解构的方式传递了一些值,给这里的props进行接收。
下面还有一种有状态组件接收props的方式
class List extends React.Component {
render() {
let {todos} = this.props;
return (
<ul>
{todos.map((todo, index) => <li key={index}>{todo}</li>)}
</ul>
)
}
}
在有状态组件中,我们用this.props进行接收。那么问题来了,我们怎么对接收的props进行校验呢,比如说我们需要这个props的某些数据是指定的类型,这时候我们就需要使用react的校验包了。
校验包prop-types的cdn地址是 https://cdn.staticfile.org/prop-types/15.6.1/prop-types.js
怎么校验props的值?
我们在接收props的组件使用,具体使用如下
Person.propTypes = {
name : PropTypes.string.isRequired,
age: PropTypes.number
};
上面的例子在所有的状态组件和无状态组件都可以用,有一种是状态组件独有的。
static propTypes = {
addComment: PropTypes.func.isRequired
};
上面的例子是状态组件独有的,他添加了一个静态属性到组件对象上。
从上面的例子我们不难看出,使用方法很简单,即为person添加一个propTypes的对象,对象里面的属性即是props的参数
有多少种校验类型?
下面的代码过于多,所以这里我总结一下,常用的就是校验props的数据类型有,比如数组(array)、布尔(bool)、函数(func)、数字(number)、symbol(ES6新增,symbol)、对象(object)、节点(node)、自定义的组件(element)等
import React from 'react';
import PropTypes from 'prop-types';
class MyComponent extends React.Component {
render() {
// 利用属性做更多得事
}
}
MyComponent.propTypes = {
//你可以定义一个属性是特定的JS类型(Array,Boolean,Function,Number,Object,String,Symbol)。默认情况下,这些都是可选的。
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
//指定类型为:任何可以被渲染的元素,包括数字,字符串,react 元素,数组,fragment。
optionalNode: PropTypes.node,
// 指定类型为:一个react 元素
optionalElement: PropTypes.element,
//你可以类型为某个类的实例,这里使用JS的instanceOf操作符实现
optionalMessage: PropTypes.instanceOf(Message),
//指定枚举类型:你可以把属性限制在某些特定值之内
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// 指定多个类型:你也可以把属性类型限制在某些指定的类型范围内
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// 指定某个类型的数组
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// 指定类型为对象,且对象属性值是特定的类型
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
//指定类型为对象,且可以规定哪些属性必须有,哪些属性可以没有
optionalObjectWithShape: PropTypes.shape({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),
// 指定类型为对象,且可以指定对象的哪些属性必须有,哪些属性可以没有。如果出现没有定义的属性,会出现警告。
//下面的代码optionalObjectWithStrictShape的属性值为对象,但是对象的属性最多有两个,optionalProperty 和 requiredProperty。
//出现第三个属性,控制台出现警告。
optionalObjectWithStrictShape: PropTypes.exact({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),
//加上isReqired限制,可以指定某个属性必须提供,如果没有出现警告。
requiredFunc: PropTypes.func.isRequired,
requiredAny: PropTypes.any.isRequired,
})
props还有什么东西呢?
使用vue的大佬都知道插槽这么一个概念,就是说当你在一个组件内部书写html标签内容时,这些内容就是插槽,插槽是不会被浏览器渲染的,因为他被存放在了一个对象里面(react种),当你使用props的时候就可以获得这个“插槽”。
从下面的例子可以看出,可以用this.state.children来获取“插槽”的内容
<script type="text/babel">
class Component extends React.Component {
render() {
const {children} = this.props;//使用this.props.children进行获取“插槽”
return (
<div>
这是一个组件
{children}
</div>
)
}
}
const Children = function () {
return (
<div>这是子组件,也是一个插槽,通过children获取</div>
)
};
ReactDOM.render(<Component><Children/></Component>, document.getElementById('test'));
</script>