章节回顾:
什么是props
当 React 元素是用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)
转换为单个对象传递给组件,这个对象被称之为 “props”。
举个栗子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<!-- 开发模式下用development版本 -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
function Demo(props) {
console.log('props: ', props)
const {name, age, obj: {hobby, sex}} = props
return <div>
姓名{name}, 性别{sex ? '男' : '女'}, 年龄{age}, 爱好{hobby} ~
</div>
}
const obj = {
sex: 0,
hobby: 'sleep'
}
const wrap = document.querySelector('#root')
const root = ReactDOM.createRoot(wrap)
root.render(<Demo name="dilireba" age={18} obj={obj} />)
</script>
</body>
</html>
props打印结果:
根据定义来理解一下:
此时元素Demo是一个自定义的函数组件,
它接收的属性有3个:name
age
obj
值分别是:'dilireba'
18
{ hobby: "sleep", sex: 0 }
这3个属性和对应的值,都会被放到一个对象里:
{
name: "dilireba",
age: 18,
obj: {
hobby: "sleep",
sex: 0
}
}
所组成的这个对象,就是props
。
props以参数的形式,传给自定义组件<Demo />
同时,还可以看到,传递参数的写法,也不是乱写的。
传递字符串可以直接写
name="dilireba"
传递数字、对象、数组、变量等,都要用{ }
包起来
age={18}
obj={obj}
因为JSX中是使用js表达式的。
JSX中的true
false
null
undefined
不会被渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<!-- 开发模式下用development版本 -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
function Demo(props) {
return <div>
{undefined}
</div>
}
const obj = {
sex: 0,
hobby: 'sleep'
}
const wrap = document.querySelector('#root')
const root = ReactDOM.createRoot(wrap)
root.render(<Demo />)
</script>
</body>
</html>
页面渲染结果:是一片空白区域
props的只读性和纯函数
props是外界传递给组件的参数
。
组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。
怎么理解呢?
写这样一个栗子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<!-- 开发模式下用development版本 -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
function Demo(props) {
props = {
name: props.name + Date.now()
}
return <div>
{props.name}
</div>
}
const wrap = document.querySelector('#root')
const root = ReactDOM.createRoot(wrap)
root.render(<Demo name="dilireba" />)
</script>
</body>
</html>
每刷新一次页面,会发现页面渲染的结果都不一样,
而传给Demo组件的name值并没有变,只是在Demo组件内部,
把props的值给修改了。
这就会导致一个问题:
不管传入的值是什么,页面渲染的结果都无法预知,都是不可控的。
所以,React有一条严格的规范:
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。
react内的数据变化,是通过state
来完成的。
纯函数
像上面举出的栗子,传入的参数相同,但是输出的值不同,
这种不是纯函数。
而依照react的规则,只要传入的参数相同,输出的值就不变,这种函数,
就叫纯函数