一、组件 & Props
1、在函数组件中使用 props
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 定义字符编码 -->
<meta charset="UTF-8">
<!-- 引入react核心库 -->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- 引入react-dome 支持react操作dom -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 引入babel 将jsx转换为js -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<!-- 定义网页标题 -->
<title>React</title>
</head>
<body>
<div id="box"></div>
<script type="text/babel">
function Cpn(props) {
return (
<div>
<span>name:{props.name}</span>
</div>
)
}
ReactDOM.render(<Cpn name="Ralph" />, document.getElementById('box'))
</script>
</body>
</html>
props属性是默认传递的,默认值是一个空对象,它会自动收集定义在组件上的属性,并绑定到props对象上。
-
当属性过多时,我们可以使用对象的方式传递
attr
<script type="text/babel"> function Cpn(props) { return ( <div> <p>name:{props.name}</p> <p>age:{props.age}</p> <p>gender:{props.gender}</p> </div> ) } // 定义需要传递的属性 const attr = { name: 'Ralph', age: 20, gender: 'man' } ReactDOM.render(<Cpn {...attr} />, document.getElementById('box')) </script>
注意:扩展运算符是不能直接去扩展一个对象的,因为对象不存在
iterator
接口的,所以我们需要通过{...obj}
的形式扩展一个对象,在React
中{}
并不是代表一个对象,而是说明在此处可以使用javascript表达式,React
会自动去识别当前的对象并将其扩展。 -
通过
prop-types
依赖包对props属性的类型进行检查1、引入
prop-type
依赖包<script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>
2、设置实例静态属性
propTypes
定义属性的接收类型Cpn.propTypes = { name: PropTypes.string.isRequired, age: PropTypes.number.isRequired, gender: PropTypes.string }
上述代码中,
PropTypes
是由prop-types
依赖包所提供的关键字,它对外提供了一系列 验证器 ,可用于确保组件接收到的数据类型是有效的。string
代表定义的属性必须为字符串类型,isRequired
代表定义的属性是必传的。3、对props中的属性定义初始值(默认值)
Cpn.defaultProps = { gender: 'man' }
2、在类组件中使用 props
<script type="text/babel">
class Cpn extends React.Component {
render (){
return (
<div>
<p>name:{this.props.name}</p>
<p>age:{this.props.age}</p>
<p>gender:{this.props.gender}</p>
</div>
)
}
}
// 定义属性的类型
Cpn.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
gender: PropTypes.string
}
Cpn.defaultProps = {
gender: 'man'
}
// 定义需要传递的属性
const attr = {
name: 'Ralph',
age: 20
}
ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
</script>
细心观察,可以发现类组件中的render函数中,我们可以使用
this.props
拿到父组件传递过来的props
,我们不妨可以大胆猜测,当我们自定义一个函数时,是否同样也能通过this.props
拿到我们想要的结果。
<script type="text/babel">
class Cpn extends React.Component {
constructor() {
this.getProps()
}
render (){
return (
<div>
<p>name:{this.props.name}</p>
<p>age:{this.props.age}</p>
<p>gender:{this.props.gender}</p>
</div>
)
}
// 自定义方法
getProps (){
console.log(this.props)
}
}
// 定义属性的类型
Cpn.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
gender: PropTypes.string
}
Cpn.defaultProps = {
gender: 'man'
}
// 定义需要传递的属性
const attr = {
name: 'Ralph',
age: 20
}
ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
</script>
运行效果如下:
我们仔细观察报错信息,不难发现,它是想提示我们要在this之前去调用一次 super
,好的,我们按照提示加上这个关键字
<script type="text/babel">
class Cpn extends React.Component {
constructor() {
super()
this.getProps()
}
render (){
return (
<div>
<p>name:{this.props.name}</p>
<p>age:{this.props.age}</p>
<p>gender:{this.props.gender}</p>
</div>
)
}
// 自定义方法
getProps (){
console.log(this.props)
}
}
// 定义属性的类型
Cpn.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
gender: PropTypes.string
}
Cpn.defaultProps = {
gender: 'man'
}
// 定义需要传递的属性
const attr = {
name: 'Ralph',
age: 20
}
ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
</script>
运行效果如下:
我们再去仔细阅读官网,官网上有这样一句话:Class 组件应该始终使用 props 参数来调用父类的构造函数。
好的,我改!!!
<script type="text/babel">
class Cpn extends React.Component {
constructor(props) {
super(props)
this.getProps()
}
render (){
return (
<div>
<p>name:{this.props.name}</p>
<p>age:{this.props.age}</p>
<p>gender:{this.props.gender}</p>
</div>
)
}
// 自定义方法
getProps (){
console.log(this.props)
}
}
// 定义属性的类型
Cpn.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
gender: PropTypes.string
}
Cpn.defaultProps = {
gender: 'man'
}
// 定义需要传递的属性
const attr = {
name: 'Ralph',
age: 20
}
ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
</script>
效果如下:
此时,效果正是我们想要的效果,并得到一条结论:当我们重写构造函数时应该要通过 super 关键字调用父类构造函数,并传入props作为参数
接下来让我们利用 Es6
语法改善一下代码
<script type="text/babel">
class Cpn extends React.Component {
static defaultProps = {
gender: 'man'
}
static propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
gender: PropTypes.string
}
render (){
return (
<div>
<p>name:{this.props.name}</p>
<p>age:{this.props.age}</p>
<p>gender:{this.props.gender}</p>
</div>
)
}
}
// 定义需要传递的属性
const attr = {
name: 'Ralph',
age: 20
}
ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
</script>