state
- 状态机: 讨论组件的data数据! 叫做state!
- 注意:只有类组件有状态机,函数组件没有!
class LiComponent extends React.Component{
state={isHot:true} //1、定义state
changeWeather=()=>{ //利用箭头函数的this指向
this.setState({isHot:!isHot}) //3、修改state需要借助特定的api setState,不能通过this.state.isHot = !this.state.isHot这种方式直接修改
//如果修改之后,想要再次获取,需要用到setState的第二个参数
//this.setState({isHot:!isHot},()=>{console.log(this.state.isHot)})
}
//2、使用state
Render(<h1 onClick={changeWeather}>今天天气{isHot?'热':'凉'}</h1>)
}
props 可实现父子通信
父传子
// 父模板里面
<子组件名 属性名="属性值" 属性名2={变量} />
<LiComponent name="张三" age={18} />
// 属性太多时,可 批量传递标签属性!!!!
var p = {name:'hah',age:10}
<LiComponent {...p} />
// 子组件里面!!!
// 类组件
this.props 表示了 组件传入的数据!
// 函数组件
function 组件名(props){
props 表示了 组件传入的数据!
}
- 不允许修改props!!!不能违背单向数据流!
- props的验证: props的验证依赖于prop-types模块,不用下载,直接使用!
props的验证:
import PropTypes from 'prop-types';
//props 类型、必传限制,默认值 简写,使结构更清晰
class Person extends React.Component{
// 需要给类本身添加属性 用static
static propTypes={
name:PropTypes.string.isRequired,
age:PropTypes.number,
speak:func,
}
static defaultProps={
name:'张三'
}
// state 给类的实例对象添加属性,直接写即可
state={}
render(){
return <h1>{thisprops.name}</h1>
}
}
子传父
-
props
-
本质: 父将一个自身的函数,传递给子组件,让子组件去调用它! 传入的父的事件函数要绑定好this的指向!否则指向props
-
实现
class 父组件 extends React.Component{ 事件函数=(形参)=>{ } render(){ return <组件 属性名={ this.事件函数 } /> } }
// 子组件模板里面 <标签 onClick={ this.props.属性名 } /> <标签 onClick={ ()=>this.props.属性名('实参') } />
兄弟之间通信:pubsub-js
A组件 订阅、取消订阅 B组件发布消息
//A组件
import PubSub from 'pubsub-js'
componentDidMount(){
this.id = PubSub.subscribe('li',(_,stateObj)=>{
this.setState(stateObj)
})
}
componnetWillUnMount(){
PubSub.unsubscribe(this.id) //组件要卸载的时候取消订阅,跟清定时器一样
}
//B组件
PubSub.publish('li',{})
##refs 属性
// 1.字符串形式的ref () ref = "btn" 获取 this.refs.btn 已不推荐使用(效率低) refs收集的是真实的dom
// 2.回调函数式的ref (调用次数问题,render调用次数1+n ref回调调用次数1+2n 第一次 null(清空) 第二次才是节点)
<input ref={(currentNode)=>{this.input1 = currentNode}} onBlur={this.showValue}/>
this.showValue=()=>{alert(this.input1.value)}
// 解决:把ref回调拿出来即可,this.saveInput 无关紧要,
推荐第二种,ref内联回调函数