React笔记-组件通信(六
props概念
props也是组件中内置的一个属性
通过父级组件传入 在类组件里 可以直接通过this.props获取
props是不可变的(只读 修改需要从传值的组件中修改
组件传值
父传子
在父组件里的子组件标签上定义属性 在子组件里使用props接收
// 父组件
import React from "react";
import LearnChild from './learn-child'
export default class LearnParent extends React.Component {
render ( {
return (
<div>
{/* 父类中的子标签中写上属性 在子类中通过props接收 */}
<LearnChild name='bob' age='18'></LearnChild>
</div>
}
}
// 子组件
import React from "react";
export default class LearnChild extends React.Component {
render ( {
return (
<div>
{/* 子类中通过this.props接收父类传值(子类标签属性 */}
<div>{this.props.name} --- {this.props.age}</div>
</div>
}
}
子修改父值
子props接收父的一个方法 父通过这个方法改变父类中的值 子每次调用接收到的父的方法 父中方法都会执行 间接改变值
子proprs接收到父传的值不能在子中被修改 子中只读
// 父组件
import React from "react";
import LearnChild from './learn-child'
export default class LearnParent extends React.Component {
state = {
age : 18
}
add (item {
this.setState({
age : ++item
}
}
render ( {
console.log(this.state.age
return (
<div>
{/* 父类中的子标签中写上属性 在子类中通过props接收 */}
<LearnChild name='bob' age={this.state.age} ageChange={(item => this.add(item}></LearnChild>
</div>
}
}
// 子组件
import React from "react";
export default class LearnChild extends React.Component {
addAge (item {
console.log(this.props.age
this.props.ageChange(item
}
render ( {
return (
<div>
{/* 子类中通过this.props接收父类传值(子类标签属性 */}
<div>{this.props.name} --- {this.props.age}</div>
<button onClick={( => this.addAge(this.props.age}>age+1</button>
</div>
}
}
子传父
父组件给子组件传入一个方法 子组件接收这个方法 在对应的事件里触发接收到的方法 并且可以传参
// 父组件
import React from "react";
import LearnChild from './learn-child'
export default class LearnParent extends React.Component {
add (item {
console.log('父类接收到: ' + item
}
render ( {
console.log(this.state.age
return (
<div>
<LearnChild name='bob' age={this.state.age} ageChange={(item => this.add(item}></LearnChild>
</div>
}
}
// 子组件
import React from "react";
export default class LearnChild extends React.Component {
addAge (item {
this.props.ageChange(item
}
render ( {
return (
<div>
{/* 子类中通过this.props接收父类传值(子类标签属性 */}
<div>{this.props.name} --- {this.props.age}</div>
<button onClick={( => this.addAge('子传父'}>age+1</button>
</div>
}
}
组件嵌套
组件标签中间如果有其他组件或者标签,则在组件内使用this.props.children展示
//父组件
import React from "react";
import Component from "./component";
import Content from "./Content";
export default class LearnPropsChild2 extends React.Component {
render( {
return (
<div>
<Component>
{/* 可以放标签 */}
<div>在组件内部的内容</div>
{/* 也可以直接放组件 */}
<Content></Content>
</Component>
</div>
;
}
}
// 子组件
import React from "react";
export default class Component extends React.Component {
render( {
return (
<div>
<div>头部</div>
{/* 通过children展示 */}
{this.props.children}
<div>底部</div>
</div>
;
}
}
受控组件
在HTML中 表单标签 值通常是根据用户输入来更新 在React可变状态通常放在组件的state中 并且只能使用setState更新
// 实例
import React from 'react'
export default class MyInput extends React.Component {
state = {
value: 0
}
handleChange = (event=>{
this.setState({
value: event.target.value
}
}
render({
return(
<div>
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
</div>
}
}
受控组件更新state流程
可以通过初始state中设置表单的默认值
- 每当表单的值发生变化时,调用onChange事件处理器
- 事件处理器通过事件对象event拿到改变后的状态,并更新组件的state
- 一旦通过setState方法更新state,就会触发视图的重新渲染,完成表单组件的更新
状态提升(同级传值
多个组件需要共享state数据时 将这些数据提升到父组件中 这就是'状态提升'
当多个组件渲染同一数据 但是状态各不相同时 这些组件数据需要同步变化 但是组件之间不能相互作用
官网例子: 一个组件用华氏度展示数据A 另一个组件用摄氏度展示数据A 数据相同 但是表现形式不同 并且当数据A被修改时 两个组件需要根据不同展现形式同时变化
import React from "react";
class Son extends React.Component {
// 1.获取组件自身input值 并传给父组件
change(event {
this.props.onShow(event.target.value;
}
render ( {
return (
<div>
<input type="text" onChange={(event => this.change(event} value={this.props.data}/>{this.props.unit}
</div>
}
}
export default class NewState2 extends React.Component {
state = {
m : 0,
cm : 0
}
changeM(m {
// 2.接收子组件m传过来的实参 并根据实参改变另一个组件中的数据 达成同步变化
this.setState({
m : m,
cm : m * 100
}
}
changeCM(cm {
// 2.接收子组件cm传过来的实参 并根据实参改变另一个组件中的数据 达成同步变化
this.setState({
m : cm / 100,
cm : cm
}
}
render ( {
return (
<div>
<Son unit='M' onShow={(m => this.changeM(m} data={this.state.m}></Son>
<Son unit='CM' onShow={(cm => this.changeCM(cm} data={this.state.cm}></Son>
</div>
}
}