1、属性(props)
props
正常是外部传入的,组件内部也可以通过一些方式来初始化的设置,属性不能被组件自己更改,但是你可以通过父组件主动重新渲染的方式来传入新的 props。
通过箭头函数创建的函数式组件,需要通过函数的参数来接收props
:
通过类创建的类组件,需要通过 this.props来接收属性
import React from 'react'
const Header = (props) => {
return (
<header>
{ props.name } 的核心库只关注于视图层
</header>
)
}
const Content = ({ name }) => (
<section>{ name }</section>
)
class Footer extends React.Component {
render () {
return (
<footer>{ this.props.name }</footer>
)
}
}
const App = () => (
<div>
<Header name="react.js"></Header>
<Content name = "react"></Content>
<Footer name="react.js"></Footer>
</div>
)
export default App
2、状态(state)
状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态的目的就是为了在不同的状态下使组件的显示不同(自己管理)
(1) 定义state
import React, { Component } from 'react'
export default class App extends Component {
// 借用了es7的类的实例属性的特性设定了类组件的状态
state = {
count: 100
}
render() {
return (
<div>
{
this.state.count
}
</div>
)
}
}
(2) setState
import React, { Component } from 'react';
export default class App extends Component {
state = {
isLiked: false
}
render() {
return (
<div>
<button onClick={ () => {
// this.state.isLiked = !this.state.isLiked 错误的
this.setState({
isLiked: !this.state.isLiked
}, () => { // 修改完状态的回调
console.log('1', this.state.isLiked)
})
// 发现不能实时获取到最新的数据 - 进一步说明 setState 不是一个同步操作
console.log(this.state.isLiked)
} }>
{ this.state.isLiked ? '❤️喜欢' : '💔不喜欢'}
</button>
</div>
);
}
}
setState
有两个参数
第一个参数可以是对象,也可以是方法return一个对象,我们把这个参数叫做updater
参数是对象:
this.setState({
isLiked: !this.state.isLiked
})
参数是方法:
import React, { Component } from 'react';
export default class App extends Component {
state = {
isLiked: false
}
render() {
return (
<div>
<button onClick={ () => {
// 第一个参数为函数,函数的第一个参数为上一次的状态
this.setState((prevState, props) => {
return {
isLiked: !prevState.isLiked
}
}, () => {
console.log('2', this.state.isLiked)
})
// 发现不能实时获取到最新的数据 - 进一步说明 setState 不是一个同步操作
console.log(this.state.isLiked)
} }>
{ this.state.isLiked ? '❤️喜欢' : '💔不喜欢'}
</button>
</div>
);
}
}
注意的是这个方法接收两个参数,第一个是上一次的state, 第二个是props
setState
是异步的,所以想要获取到最新的state,没有办法获取,就有了第二个参数,这是一个可选的回调函数
3、属性vs状态
相似点:都是纯js对象,都会触发render更新,都具有确定性(状态/属性相同,结果相同)
不同点:
-
属性能从父组件获取,状态不能
-
属性可以由父组件修改,状态不能
-
属性能在内部设置默认值,状态也可以
-
属性不在组件内部修改,状态要改
-
属性能设置子组件初始值,状态不可以
-
属性可以修改子组件的值,状态不可以
state
的主要作用是用于组件保存、控制、修改自己的可变状态。state
在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。你可以认为 state
是一个局部的、只能被组件自身控制的数据源。state
中状态可以通过 this.setState
方法进行更新,setState
会导致组件的重新渲染。
props
的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props
,否则组件的 props
永远保持不变。
如果搞不清 state
和 props
的使用场景,记住一个简单的规则:尽量少地用 state
,多用 props
。
没有 state
的组件叫无状态组件(stateless component),设置了 state 的叫做有状态组件(stateful component)。因为状态会带来管理的复杂性,我们尽量多地写无状态组件,尽量少地写有状态的组件。这样会降低代码维护的难度,也会在一定程度上增强组件的可复用性。