文章目录
一、state
1.state的初始化
状态(state),本质上是类组件的一个属性,是一个对象,状态是由组件自行维护,状态需要初始化,组件有权改变状态里的数据。
初始化的方式有两种:
1.写在constructor里:
import React, {
Component } from 'react'
export default class App extends Component {
constructor(){
super()
this.state = {
num:1
}
}
render() {
return (
<div>
<h1>{
this.state.num}</h1>
<button onClick={
()=>{
this.setState({
num:this.state.num + 1})}}>+</button>
</div>
)
}
}
2.写在外部:
import React, {
Component } from 'react'
export default class App extends Component {
state = {
num:1
}
render() {
return (
<div>
<h1>{
this.state.num}</h1>
<button onClick={
()=>{
this.setState({
num:this.state.num + 1})}}>+</button>
</div>
)
}
}
2.state的改变
关于状态的改变:
我们并不能像vue一样直接修改数据而触发视图更新,因为react无法监控到状态发生变化,所以我们可以通过调用this.setState去改变状态,一旦调用了this.setState,会导致当前组件重新渲染。
二、props
在讲props之前,需要明确react的哲学:数据属于谁,谁才有权利改动数据。
数据自顶而下流动,数据属于谁,谁才有权利改变该数据。
组件里的props是一个对象,里面的数据来自父元素。
1.类组件里的props
父组件:App
import React from 'react';
import ReactDOM from 'react-dom';
import MyClassComp from "./MyClassComp"
ReactDOM.render(<div>
<MyClassComp number = {
5}/>
</div>,document.getElementById("root"))
子组件:MyClassComp
import React from 'react'
export default class MyClassComp extends React.Component {
constructor(props){
super(props); //this.prosps = props,先调用父类的构造函数,把props保存到super的属性里、
}
render() {
return <h1>类组件内容,数字:{
this.props.number}</h1> //数据是父元素传来的5
}
}
2.函数组件里的props
父组件:App
import React from 'react';
import ReactDOM from 'react-dom';
import MyFuncComp from "./MyFuncComp"
ReactDOM.render(<div>
<MyFuncComp number = {
7}/>
</div>,document.getElementById("root"))
子组件:MyFuncComp
import React from "react"
export default function MyFuncComp(props){
return <h1>函数组件内容,目前的数字:{
props.number}</h1> //输出父组件传过来的7
}
三、refs
1. 字符串形式的ref(这种方式已经过时了)
给ref直接赋值字符串(这个形式有点像vue的ref),如:
import React, {
Component } from 'react'
export default class App extends Component {
render() {
return (
<div>
<input type="text" ref="myRef" />
<button onClick={
()=>{
console.log(this.refs.myRef)}}>ref</button>
</div>
)
}
}
以下是打印的this实例,可以看出this的refs属性里多个一个myRef属性,值就是选中的元素:
注意:
- ref作用于内置的html组件,得到的将是真实的dom对象
- ref作用于类组件,得到将是类的实例
- ref不能作用于函数组件
2. 对象形式的ref
调用react.createRef,返回值是一个对象,该对象有个current属性,然后把该对象赋值给ref,如:
import React, {
Component,createRef } from 'react'
export default class App extends Component {
constructor(){
super()
this.txt = createRef()
}
render() {
return (
<div>
<input type="text" ref={
this.txt} />
<button onClick={
()=>{
console.log(this)}}>ref</button>
</div>
)
}
}
//如果不用react.createRef,上面的写法等同于:
import React, {
Component } from 'react'
export default class App extends Component {
constructor(){
super()
this.txt = {
current:null,
}
}
render() {
return (
<div>
<input type="text" ref={
this.txt} />
<button onClick={
()=>{
console.log(this)}}>ref</button>
</div>
)
}
}
以下是打印的this实例,可以看出this的txt对象里有个current属性,值就是选中的元素:
关于函数的调用时间:
- 在componentDidMount生命周期及之后可以使用ref,因为元素已经挂载。
- 如果ref的值发生了变动,绑定的函数会被调用两次,为了避免这种情况,可以把绑定的函数放在类里,调用时就不会触发两次了。时间点出现在componentDidUpdate之前,旧的函数被调用时,传递null,新的函数被调用时,传递对象
- 如果ref所在的组件被卸载,会调用函数
3. 函数形式的ref
给ref属性赋值一个函数,该函数的参数就是想要选中的元素,在函数内部将该值赋予在this实例上,如:
import React, {
Component } from 'react'
export default class App extends Component {
constructor(){
super()
}
render() {
return (
<div>
<input type="text" ref={
ele=>{
this.myInput = ele}} />
<button onClick={
()=>{
console.log(this)}}>ref</button>
</div>
)
}
}
以下是打印的this实例,可以看出this上有个myInput属性,值就是选中的元素:
总结
1.state只维护当前组件的状态,改变状态需要调用this.setState,传入的对象采用混入的方式。
2. 数据属于谁谁才有权利改变,props的值不可直接改变。
3. ref本质是一种反模式,勿滥用。