React--8: 组件的三大核心属性2:props

185 阅读4分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

1. props的基本使用

当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。

接收组件标签传入的参数。

    render(){
        return(
            <ul>
                <li>
                    姓名 :{this.props.name}
                </li>
                <li>
                    性别 :{this.props.sex}
                </li>
                <li>
                    年龄:{this.props.age}
                </li>
            </ul>
        )
    }
}
// 2. 渲染
ReactDOM.render(<Person name="tom" age={18} sex="girl"/>, document.getElementById('root'))

组件标签中传参:字符的可以使用引号,数值使用{数字}的形式。

如果觉得写多个 this.props 比较麻烦,我们可以解构出三个变量。

     render(){
        const {name,sex,age} = this.props
        return(
            <ul>
                <li>
                    姓名 :{name}
                </li>
                <li>
                    性别 :{sex}
                </li>
                <li>
                    年龄:{age}
                </li>
            </ul>
        )
    }

当我们想渲染出多个列表的时候(当然这不是很好),可以通过ReactDOM.render 创建多个Person的实例对象。


ReactDOM.render(<Person name="tom" age={18} sex="girl"/>, document.getElementById('root'))
ReactDOM.render(<Person name="bob" age={21} sex="boy"/>, document.getElementById('root'))
ReactDOM.render(<Person name="luck" age={18} sex="girl"/>, document.getElementById('root'))

2.批量传递(标签属性)

当需要传递的参数有十几二十个的时候怎么办?我们不可能都写在标签中。

并且这些要传递的参数,正常来说都是走ajax请求后端接口的。

我们声明一个对象,然后在标签中用{...}来传递参数。

const p = {name:'tom',age:18,sex:'girl'}
ReactDOM.render(<Person {...p}/>, document.getElementById('root'))

展开运算符:

展开数组

let arr1 = [1,3,5,7,9]
let arr2 = [2,4,6,8,10]
console.log(...arr1)   // 1 3 5 7 9
console.log(arr1)      // [1,3,5,7,9]

连接数组

let arr1 = [1,3,5,7,9]
let arr2 = [2,4,6,8,10]
let arr3 = [...arr1,...arr2]
console.log(arr3)    // [1,3,5,7,9,2,4,6,8,10]

函数传参

function sum(a,b,c){
    return a+b+c
}
sum(1,2,3,4,5,6,7,8,9)   // 当参数是不固定的情况下怎么办?

当参数是不固定的情况下怎么办?此时将函数的参数改为

function sum(...numbers){
    console.log(numbers)   // 会是个数组[]
}

数组求和 reduce

reduce是有返回值的

function sum(...numbers){
   numbers.reduce((preValue,currentValue)=>{
       return preValue + currentValue
   })
}

复制对象同时修改

这是个合并操作

let person3 = {...person,name:"jetty",address:"home"}

思考一下

⚠️ ES6语法中

三点运算符不能展开一个对象。但是可以复制一个对象:用大括号包着 {...person}

⚠️ React语法中

再看一下我们上面的代码 <Person {...p}/> ,现在的 {} 和 ES6表达的 是一个意思吗?

当然不是,现在的 {}表示的是我要写 js代码了。 所以我们传递的参数就是 ...p。

这是因为经过了Babel和react的处理。且只适用于标签属性的传递

3. 对props进行限制

需求1

我们想让每个人的年龄在展示时都加一

在渲染的时候都加一,但是如果对象中的age是字符串类型

class Person extends React.Component{
    render(){
        const {name,sex,age} = this.props
        return(
            <ul>
                <li>
                    姓名 :{name}
                </li>
                <li>
                    性别 :{sex}
                </li>
                <li>
                    年龄:{age+1}
                </li>
            </ul>
        )
    }
}
// 2. 渲染
const p = {name:'tom',age:'18',sex:'girl'}

我们的效果就变成了字符串的拼接

image.png

有一个问题,我们不使用批量传参数,我们还用之前的单个传参数

    <Person name="yy" age=18 sex="girl"/>,

这样可以吗?当然不可以。那么要传递数值型的参数怎么办?是不是只有js才会有数值型这个概念。 所以 age = {}, {}代表我要js代码了。

进行限制

当我们想要组件的传参限制类型时、当传空给默认值时、当某个参数必须传时。 我们需要在哪里做限制呢?在类的实例上 首先引入PropTypes

import PropTypes from 'prop-types';

限制参数类型

注意区分两个 propTypes 的大小写

   Person.propTypes = {
        name :PropTypes.string,
    }

接下来把我们的 name 传 数值型的参数,报错了(期待字符串但是得到的是数值)。虽然报错但是还是保证了页面的正常显示。

image.png

限制必填

在后面写入关键字 isRequired

   Person.propTypes = {
        name :PropTypes.string.isRequired,
    }

当我们不传递参数 name 时,会报错 image.png

默认值

defaultProps 属性

Person.defaultProps = {
    name : "tom"
}

当我们不传递 name 参数时就会默认 tom image.png

对函数限制

注意函数类型是 func 并不是 function

image.png

image.png

完整代码

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import './index.css';
class Person extends React.Component{
    render(){
        const {name,sex,age} = this.props
        this.props.name = "pak"
        return(
            <ul>
                <li>
                    姓名 :{name}
                </li>
                <li>
                    性别 :{sex}
                </li>
                <li>
                    年龄:{age+1}
                </li>
            </ul>
        )
    } 
}
Person.propTypes = {
    name :PropTypes.string.isRequired,
    sex : PropTypes.string,
    speak : PropTypes.func
}
Person.defaultProps = {
    name : "tom"
}
function  speak(){
    console.log("speak")
}
// 2. 渲染
const p = {age:'18',sex:'girl'}
ReactDOM.render(<Person name="bob" sex="girl" age={12} speak={222}/>, document.getElementById('root'))

4. props的简写方式

props是只读的

props 是只读的。当我们再去修改 props 中的值时会报错。

image.png

image.png

写到类的内部 (static关键字)

defaultProps、propTypes都是在给类的自身加属性。那么能给它们写到类的内部吗? 将 defaultProps、propTypes 剪切到类的内部,将 Person.propTypes 改成 static 关键字。有了static关键字,就不会再加给类的实例,而是加给类

    static propTypes = {
        name :PropTypes.string.isRequired,
        sex : PropTypes.string,
    }
    static defaultProps = {
        name : "tom"
    }