1.组件之间的通讯
介绍
:组件都是独立的,只能使用组件自己的数据。在组件化的过程中,将本来一个完整功能的组件,拆分成多个组件,以方便更好的维护,但是这样一来,多个组件之间就需要共享数据,就需要打破组件独立封闭的特性,这一过程叫做组件之间的通信
1.1.props通信
- 接受传递给子组件的数据
- 传递数据需要给子组件设置自定义属性,将父组件的数据传递过去
- 函数组件提供props形参来获取数据,类组件通过this.props来获取数据
子组件给父组件传递参数
:
// 函数子组件
function Child (props) {
console.log(props)
return (
<div>{ props.name }</div>
)
}
// 类子组件
class Child2 extends Component {
constructor (props) {
super(props)
this.state = {}
}
render () {
console.log(this.props)
return (
<div>{ this.props.name }</div>
)
}
}
// 父组件
class Father extends Component {
constructor (props) {
super(props)
this.state = {
name: '小美'
}
}
render () {
return (
<div>
<Child name={ this.state.name } />
<Child2 name={ this.state.name } />
</div>
)
}
}
子组件给父组件传递数据
:利用父组件定义的方法,传递给子组件,有子组件来调用方法将数据传递给函数
// 类子组件
class Child2 extends Component {
constructor (props) {
super(props)
this.state = {
name: '小红'
}
}
btnClick = () => {
// 点击按钮之后调用父组件的方法,将自己的数据传递过去
this.props.fn(this.state.name)
}
render () {
return (
<button onClick={ this.btnClick }>点击给父组件传递数据</button>
)
}
}
// 父组件
class Father extends Component {
constructor (props) {
super(props)
this.state = {
name: '小美'
}
}
// 此方法由子组件调用传递参数
child2Fn = (data) => {
console.log(data)
this.setState({
name: data
})
}
render () {
return (
<div>
<Child2 fn={ this.child2Fn } />
</div>
)
}
}
兄弟组件传递参数
:将共享的状态提升到父组件中去定义,由公共的父组件管理这些状态,并且提供方法给子组件修改状态或者提供状态。而影响另一个子组件。
// 类子组件2
class Child2 extends Component {
constructor (props) {
super(props)
this.state = {
name: '小颖'
}
}
btnClick = () => {
this.props.fn(this.state.name)
}
render () {
return (
<button onClick={ this.btnClick }>点击给父组件传递状态数据</button>
)
}
}
// 类子组件1
class Child1 extends Component {
constructor (props) {
super(props)
this.state = {
name: ''
}
}
render () {
return (
// 兄弟组件的数据
<span>{ this.props.name }</span>
)
}
}
// 父组件
class Father extends Component {
constructor (props) {
super(props)
this.state = {
name: '小美'
}
}
// 接受子组件修改状态的新数据
editData = (data) => {
this.setState({
name: data
})
}
render () {
return (
<div>
<Child2 fn={ this.editData } />
<Child1 name={ this.state.name } />
</div>
)
}
}
Context介绍
:使用与多层嵌套传值,列入跟组件给子孙的子孙组件传值,如果还使用上面的的方法,会显得很复杂。这个使用就可以使用Context来解决这个问题
// 1.先引入进来
const { Provider, Consumer } = React.createContext()
// 2.介绍
// Provider:是提供数据的组件
// Consumer :是消费数据的组件
// 3.使用
// 祖先组件
class Com extends React.Component {
state = {
age: 10,
name: 'as',
sex: '',
data: {
name: '小美',
age: 20
}
}
fn = () => {
}
render () {
return (
<div>
// 定义数据,只能传递一个参数,所以这个参数可以是对象,或者数组
<Provider value={ { name: this.state.name, age: this.state.age } }>
<Child1 bi={ this.state.age } />
</Provider>
</div>
)
}
}
// 子组件
class Child2 extends React.Component {
state = {}
render () {
return (
// 消费数据
<Consumer>
{
({ age }) => {
return (
<span>{ age }</span>
)
}
}
</Consumer>
)
}
}
children属性
:表示该组件标签的子节点。当组件标签有子节点时。props就会拥有该属性
function Home (props) {
return (
console.log(props)
<div>{ props.children }</div>
)
}
// 渲染出去
<Home>我是子节点</Home>
props效验
:对于组件来说props是外来的,所以并不知道具体的数据类型,所以在使用的过程中容易报错。无法确定具体的数据的类型。使用prop-types可以用来效验数据类型
// 1.先下载下来这个包
npm i prop-types
cnpm i prop-types
yarn add prop-types
// 2.导入prop-types的包
import propTypes from 'prop-types';
// 3.使用
// 函数组件
function Hello (props) {
return (
<div>
<div>组件的子节点:{ props.name.name }</div>
<div>哈哈{props.gender}</div>
<div>性别:{props.age}</div>
</div>
)
}
// propTypes:效验参数props
Hello.propTypes = {
gender: propTypes.number,
name: propTypes.shape({
name: propTypes.string
})
}
// defaultProps:默认参数,如果父组件不传递参数,那么久使用 defaultProps里面定义的默认数据
Hello.defaultProps = {
age: '女'
}
// 父组件传递的参数格式
state = {
gender: 20,
name: {
name: '哈哈'
}
}
// 常见的效验类型的数据
array、bool、func、number、object、string