组件实例的三大核心属性
注:只有类式组件才有该核心属性,函数式组件没有
state
理解
- state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合)
- 组件被称为“状态机”,通过更新组件的state来更新对应的页面显示(重新渲染组件)
示例
<div id="test"></div>
<script type="text/babel">
// 1.创建组件
class Weather extends React.Component{
//构造器只调用一次
constructor(props){
super(props)
//初始化状态
this.state = {isHot:false}
//解决changeWeather中this指向问题
this.changeWeather = this.changeWeather.bind(this)
}
//render调用 1+n 次 1是初始化的那次,n是状态更新的次数
render(){
//读取状态
const {isHot} = this.state
return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'}</h1>
}
//changeWeather点几次调几次
changeWeather(){
//changeWeather放在哪里?——Weather的原型对象上,供实例使用
//由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined
//获取原来的isHot值
const isHot = this.state.isHot
//注:状态不可直接更改,必须通过setState进行更新,且更新是一种合并,不是替换
this.setState({isHot:!isHot})
}
}
// 2.渲染组件到页面
ReactDOM.render(<Weather/>, document.getElementById('test'))
</script>
注意点:
- render()中 return<h1>中的 onClick 第三个字母为大写
- onClick = changeWeather() 这种写法是错误的,正确写法为 onClick = {changeWeather},将changeWeather作为onClick的回调函数
- 相同背景颜色处的名称必须一致
- 修改状态:this.state.isHot = !isHot (此写法为直接更改,react不支持直接更改,需通过调用React.Component中的setState进行修改)
强烈注意
- 组件中的 render 方法中的 this 为组件实例对象
- 组件自定义的方法中 this 为 undefined ,解决方法:强制绑定 this:通过函数对象的 bind();箭头函数
- 状态数据,不能直接修改或更新
props
理解
-
每个组件对象都会有props (properties的简写) 属性
-
组件标签的所有属性都保存在props中
示例
<div id="test1"></div>
<div id="test2"></div>
<div id="test3"></div>
<script type="text/babel">
//创建组件
class Person extends React.Component{
//对标签属性进行类型、必要性的限制
//PropTypes需要引入prop-type.js
static propTypes = {
name:PropTypes.string.isRequired,
age:PropTypes.number,
sex:PropTypes.string,
speak:PropTypes.func,
}
//指定默认标签属性值
static defaultProps = {
sex: '男',
age: 18
}
render(){
const {name,age,sex} = this.props
return(
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age+1}</li>
</ul>
)
}
}
//渲染组件到页面
ReactDOM.render(<Person name="jerry" speak={speak} />, document.getElementById("test1"))
ReactDOM.render(<Person name="tom" age={18} sex="女" />, document.getElementById("test2"))
const p = {name:"老刘", age:18, sex:"女"}
ReactDOM.render(<Person {...p}/>, document.getElementById("test3"))
function speak(){
console.log('我说话了');
}
</script>
注意点:
- 标签属性可使用 展开表达式 进行批量传递
- 函数式组件可以使用 props
作用
-
通过标签属性从组件外向组件内传递变化的数据
-
注意:组件内部不要修改props数据
refs
字符串形式的ref
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component{
showData = ()=>{
const {input1} = this.refs
alert(input1.value)
}
showData2 = ()=>{
const {input2} = this.refs
alert(input2.value)
}
render(){
return(
<div>
<input ref="input1" type="text" placeholder="点击按钮提示数据"/>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
</div>
)
}
}
ReactDOM.render(<Demo a="1" b="2"/>, document.getElementById('test'))
</script>
回调形式的ref
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component{
showData = ()=>{
const {input1} = this
alert(input1.value)
}
showData2 = ()=>{
const {input2} = this
alert(input2.value)
}
render(){
return(
<div>
<input ref={c => this.input1 = c} type="text" placeholder="点击按钮提示数据"/>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input ref={c => this.input2 = c} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
</div>
)
}
}
ReactDOM.render(<Demo a="1" b="2"/>, document.getElementById('test'))
</script>
createRef的使用
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component{
myRef = React.createRef()
myRef2 = React.createRef()
showData = ()=>{
alert(this.myRef.current.value)
}
showData2 = ()=>{
alert(this.myRef2.current.value)
}
render(){
return(
<div>
<input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input ref={this.myRef2} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
</div>
)
}
}
ReactDOM.render(<Demo a="1" b="2"/>, document.getElementById('test'))
</script>
事件处理
- 通过onXxx属性指定事件处理函数(注意大小写):React使用的是自定义(合成)事件,而不是使用的原生DOM事件——为了更好的兼容性;React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)——为了高效
- 通过event.target得到发生事件的DOM元素对象 ——不要过度使用ref