五、Props
5.1 Props详解
props
是正常是外部传入的,组件内部也可以通过一些方式来初始化的设置,属性不能被组件自己更改,但是你可以通过父组件主动重新渲染的方式来传入新的 props
React 非常灵活,但它也有一个严格的规则:
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。
纯函数:输入一定,输出一定确定
总的来说,在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为组件 props
对象的键值。
通过箭头函数创建的组件,需要通过函数的参数来接收props
通过类创建的组件,需要通过 this.props
来接收
组件可以在其输出中引用其他组件。
这就可以让我们用同一组件来抽象出任意层次的细节。
按钮,表单,对话框,甚至整个屏幕的内容:在 React 应用程序中,这些通常都会以组件的形式表示。
5.2 父子组件通信
5.2.1 构建一个父子组件
src/index.js
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
// 引入react组件时,后缀名可以不写
import App from './01_props/01_Parent_Child'
const root = ReactDOM.createRoot(document.querySelector('#root'))
root.render(<App />)
src/01_props/01_Parent_Child.jsx
// src/01_props/01_Parent_Child.jsx
// React组件的后缀名 既可以是js 也可以jsx
import React from 'react'
class Child extends React.Component {
render () {
return (
<div>子组件</div>
)
}
}
class Parent extends React.Component {
render () {
return (
<div>
父组件
<hr />
<Child />
</div>
)
}
}
class App extends React.Component {
render () {
return (
<div>
<h1>父子组件</h1>
<Parent />
</div>
)
}
}
export default App
5.2.2 父组件给子组件传值
src/index.js
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
// import App from './01_props/01_Parent_Child' // 父子组件省略.jsx
import App from './01_props/02_Parent_Child_value' // 父组件给子组件传值
const root = ReactDOM.createRoot(document.getElementById('root'))
// 标签形式调用
root.render(<App />)
src/01_props/02_Parent_Chil_value.jsx
// src/01_props/02_Parent_Child_value.jsx
import React from 'react'
/**
* 1.父组件在调用子组件的地方,添加自定义的属性,
* 如果属性的值是变量、boolean类型、number类型、对象、数组、null、undefined,
* 使用 {} 包裹
* 2.子组件通过props属性接收父组件传递的值
* 2.1 如果子组件是类组件,将在jsx代码中可通过 this.props 获取父组件的值
* 2.2 如果子组件是函数式组件, 默认参数为props,即可获得父组件的值
*/
const Child2 = (props) => {
return (
<div>
子组件2
<div>str: { props.str }</div>
<div>flag: { props.flag + '' }</div>
<div>num: { props.num }</div>
<div>obj.a: { props.obj.a }</div>
<div>arr: { props.arr }</div>
</div>
)
}
class Child1 extends React.Component {
render () {
return (
<div>
子组件1
<div>str: { this.props.str }</div>
<div>flag: { this.props.flag + '' }</div>
<div>num: { this.props.num }</div>
<div>obj.a: { this.props.obj.a }</div>
<div>arr: { this.props.arr }</div>
</div>
)
}
}
class Parent extends React.Component {
render () {
const str1 = 'str1'
const str2 = 'str2'
return (
<div>
父组件
<hr />
<Child1
str = { str1 }
flag = { true }
num = { 1 }
obj = { { a: 1 } }
arr = { [1, 2, 3] }
/>
<hr />
<Child2
str = { str2 }
flag = { false }
num = { 2 }
obj = { { a: 2 } }
arr = { [4, 5, 6] }
/>
</div>
)
}
}
class App extends React.Component {
render () {
return (
<div>
<h1>父子组件</h1>
<Parent />
</div>
)
}
}
export default App
5.2.3 父组件给子组件传值设置默认值
src/index.js
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
// 引入react组件时,后缀