状态就是组件描述某种显示情况的数据, 由组件自己设置和更改, 也就是说由组件自己维护, 使用状态的目的就是为了在不同的状态下使组件的显示不同(自己管理)。
第一种方式
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
state = {
name: 'React',
isLiked: false
}
render() {
return (
欢迎来到{this.state.name}的世界
)
}
}
ReactDOM.render( , document.getElementById('root'))
另一种方式
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor() {
super()
this.state = {
name: 'React',
isLiked: false
}
}
render() {
return (
欢迎来到{this.state.name}的世界
)
}
}
ReactDOM.render( , document.getElementById('root'))
this.state
是纯 js
对象, 在 vue
中, data
属性是利用 Object.defineProperty
处理过的, 更改 data
的数据的时候会触发数据的 getter
和 setter
, 但是 React
中没有做这样的处理, 如果直接更改的话, react
是无法得知的, 所以, 需要使用特殊的更改状态的方法 setState
。
isLiked
存放在实例的 state
对象当中, 组件的 render
函数内, 会根据组件的 state
的中的 isLiked
不同显示“取消”或“收藏”内容。下面给 button
加上了点击的事件监听。
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor() {
super()
this.state = {
name: 'React',
isLiked: false
}
}
handleBtnClick = () => {
this.setState({
isLiked: !this.state.isLiked
})
}
render() {
return (
欢迎来到{this.state.name}的世界
)
}
}
ReactDOM.render( , document.getElementById('root'))
setState
有两个参数第一个参数可以是对象, 也可以是方法 return
一个对象, 我们把这个参数叫做 updater
。
this.setState({
isLiked: !this.state.isLiked
})
// 注意的是这个方法接收两个参数,第一个是上一次的state, 第二个是props
this.setState((prevState, props) => {
return {
isLiked: !prevState.isLiked
}
})
setState
是异步的, 所以想要获取到最新的 state
, 没有办法获取, 就有了第二个参数, 这是一个可选的回调函数
this.setState((prevState, props) => {
return {
isLiked: !prevState.isLiked
}
}, () => {
console.log('回调里的', this.state.isLiked)
})
console.log('setState外部的', this.state.isLiked)
props
是正常是外部传入的, 组件内部也可以通过一些方式来初始化的设置, 属性不能被组件自己更改, 但是你可以通过父组件主动重新渲染的方式来传入新的 props
属性是描述性质、特点的, 组件自己不能随意更改。
之前的组件代码里面有 props
的简单使用, 总的来说, 在使用一个组件的时候, 可以把参数放在标签的属性当中, 所有的属性都会作为组件 props
对象的键值。通过箭头函数创建的组件, 需要通过函数的参数来接收 props
:
key=value
写属性,通过 this.props
获取属性, 这样组件的可复用性提高了。isShow="true"
那么这是一个字符串, 如果写成 isShow={true}
这个是布尔值{...对象}
展开赋值*.defaultProps = { }
static defaultProps = {
myname: "默认的myname",
myshow: true
}
import propTypes from "prop-types";
*.propTypes = {
name: propTypes.string,
age: propTypes.number
}
static propTypes = {
myname: propTypes.string,
myshow: propTypes.bool
}
相似点:
js
对象render
更新不同点:
state
的主要作用是用于组件保存、控制、修改自己的可变状态。 state
在组件内部初始化, 可以被组件自身修改, 而外部不能访问也不能修改。你可以认为 state
是一个局部的、只能被组件自身控制的数据源。 state
中状态可以通过 this.setState
方法进行更新, setState
会导致组件的重新渲染。
props
的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数, 组件内部无法控制也无法修改。除非外部组件主动传入新的 props
, 否则组件的 props
永远保持不变。
没有 state
的组件叫无状态组件(stateless component
), 设置了 state
的叫做有状态组件(stateful component
)。因为状态会带来管理的复杂性, 我们尽量多地写无状态组件, 尽量少地写有状态的组件。这样会降低代码维护的难度, 也会在一定程度上增强组件的可复用性。
{
condition ? '渲染列表的代码' : '空空如也'
}
// 数据
const people = [{id: 1, name: 'Leo', age: 35}, {
id: 2, name: 'XiaoMing', age: 16
}]
// 渲染列表
{
people.map(person => {
return (
- {person.name}
- age: {person.age}
)
})
}
React
的高效依赖于所谓的 Virtual-DOM
, 尽量不碰 DOM
。对于列表元素来说会有一个问题:元素可能会在一个列表中改变位置。要实现这个操作, 只需要交换一下 DOM
位置就行了, 但是 React
并不知道其实我们只是改变了元素的位置, 所以它会重新渲染后面两个元素(再执行 Virtual-DOM
), 这样会大大增加 DOM
操作。但如果给每个元素加上唯一的标识, React
就可以知道这两个元素只是交换了位置, 这个标识就是 key
, 这个 key
必须是每个元素唯一的标识。
对于富文本创建的内容, 后台拿到的数据是这样的:
content = "React.js是一个构建UI的库
"
处于安全的原因, React
当中所有表达式的内容会被转义, 如果直接输入, 标签会被当成文本。这时候
就需要使用 dangerouslySetHTML
属性, 它允许我们动态设置 innerHTML
。
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor() {
super()
this.state = {content: "React.js是一个构建UI的库
"}
}
render() {
return ({__html: this.state.content}}/>)
}
}
ReactDOM.render( , document.getElementById('root'))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17