组件分为两种
- 无状态组件(函数式组件)无状态组件可以通过props的形式来达到响应式变化
// 无状态组件 函数式组件
// 静态组件 没有状态 无法修改内容
function App() {
var count = 0
setInterval(() => {
count++
/**
* 时间调用定时器函数 每次调用count值都会变化
* 每次调用都会log一个count1 但状态没变 所以不会渲染页面
* */
console.log('count1', count)
}, 1000)
// 在此处只会log一次也就是初始渲染 因为没有状态修改 所以不会重新渲染 所以不会进行到这一步
console.log('count2', count)
var data = {
name: 'jack'
}
var arr = [1, 2, 3]
var isMan = false
var getName = () => {
return '我是函数'
}
return (
// jsx中必须使用一个父级标签包裹 可以使用一个Fragment
<>
<h1 className='app'>{count}</h1>
<h1 className='app'>{data.name}</h1>
<h1 className='app'>{arr[1]}</h1>
<h1 className='app'>{isMan ? "woman" : "man"}</h1>
<h1 className='app'>{getName()}</h1>
</>
)
}
- 有状态组件 (有state的组件)
- 老版本:
this.state = {}调用的时候使用this.state.key来调用,修改的时候使用this.setState({key: value})
class App extends React.Component {
// state(状态)
// 在组件内修改数据使用state
constructor(props) {
super(props)
this.state = {
count: 0,
door: 'open'
}
setInterval(() => {
// this.state.count++
this.setState({
// count: this.state.count++ 只有执行完后才会++ 我已经先setState之后在修改了值 将一直为0
// count: ++this.state.count 目的可以达成
count: this.state.count + 1
})
}, 1000)
}
handleClick() {
console.log('this', this)
// this的值为undefined
this.setState({
door: 'close'
})
}
// 是个独立的作用域 通过this.state来拿值
render() {
// es6的解构
const { count, door } = this.state
return (
<>
<h1 className='app'>{count}</h1>
{/* 用箭头函数来传递特定的参数 但是使用这种绑定this的方法 每次render都会生成新的函数实例 影响性能 */}
{/* <h1 onClick={(e) => this.handleClick('e', e)}>{door} 事件绑定</h1> */}
<h1 onClick={this.handleClick.bind(this)}>{door} 事件绑定</h1>
</>
)
}
}
方法二:
class App extends React.Component {
// state(状态)
// 在组件内修改数据使用state
constructor(props) {
super(props)
this.state = {
door: 'open'
}
// 绑定this的作用域
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
console.log('this', this)
this.setState({
door: 'close'
})
}
// 是个独立的作用域 通过this.state来拿值
render() {
// es6的解构
const { door } = this.state
return (
<>
<h1 onClick={this.handleClick}>{door}事件绑定</h1>
</>
)
}
}
方法三:
class App extends React.Component {
// state(状态)
// 在组件内修改数据使用state
constructor(props) {
super(props)
this.state = {
door: 'open'
}
}
// 默认传递事件对象
// 箭头函数的this在babel编译的时候 会默认绑定this
// 使用了箭头函数时 不需要在constructor中绑定this的作用域
handleClick = () => {
console.log('this', this)
this.setState({
door: 'close'
})
}
// 是个独立的作用域 通过this.state来拿值
render() {
// es6的解构
const { door } = this.state
return (
<>
<h1 onClick={this.handleClick}>{door} 事件绑定</h1>
</>
)
}
}
- 新版本:
const [value, setValue] = useState(value)(value可以是任何类型的值),调用的时候直接使用value,修改的时候直接使用setValue(newValue)
import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
// 点击button之后并不会递增三次 将只会递增一次
// 因为React 会等到事件处理函数中的 所有代码都运行完毕再处理你的 state 更新 所以number三次+1用的都是同一个值
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>+3</button>
</>
)
}