React 基础笔记 02
组件的数据挂载方式
1. 状态
状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态 的目的就是为了在不同的状态下使组件的显示不同(自己管理)
- 定义state
import React, { Component } from 'react';
class Test extends Component {
state = {
name: 'smiling' // 通过自定义变量 state
}
render() {
return (
<div>
<h1>第一种定义:{this.state.name}</h1>
</div>
);
}
}
export default Test;
import React, { Component } from 'react';
class Test extends Component {
constructor(){
super()
this.state = {
name: 'smiling' // 通过构造器
}
}
render() {
return (
<div>
<h1>第二种定义:{this.state.name}</h1>
</div>
);
}
}
export default Test;
-
setState
this.state 是纯 js 对象,在 vue 中,data 属性是利用 Object.defineProperty 处理过的,更改 data 的数据的时候会触发数据的 getter 和 setter ,但是 React 中没有做这样的处理,如果直接更改的话, react是无法得知的,所以需要使用特殊的更改状态的方法 setState
- setState 有两个参数
第一个参数可以是对象,也可以是方法return一个对象,我们把这个参数叫做 updater
import React, { Component } from 'react';
class Test extends Component {
constructor(){
super()
this.state = {
name: 'smiling'
}
}
handClick = () => {
// 参数是对象
this.setState({
name: 'ling.wang'
})
}
render() {
return (
<div>
<h1>姓名:{this.state.name}</h1>
<button onClick={this.handClick}>切换</button>
</div>
);
}
}
export default Test;
import React, { Component } from 'react';
class Test extends Component {
constructor(){
super()
this.state = {
name: 'smiling'
}
}
handClick = () => {
// 参数是函数
this.setState((prevState, props) => {
console.log(prevState, props)
return {
name: 'ling.wang'
}
}, () => {
console.log('回调里的',this.state.name)
})
console.log('setState外部的',this.state.name)
}
render() {
return (
<div>
<h1>姓名:{this.state.name}</h1>
<button onClick={this.handClick}>切换</button>
</div>
);
}
}
export default Test;
参数是函数的执行结果:
2. 属性 props
props 是正常是外部传入的,组件内部也可以通过一些方式来初始化的设置,属性不能被组件自己更 改,但是你可以通过父组件主动重新渲染的方式来传入新的 props
之前的组件代码里面有 props 的简单使用,总的来说,在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为组件 props 对象的键值。通过箭头函数创建的组件,需要通过函数的 参数来接收 props :
- 在组件上通过key=value 写属性,通过this.props获取属性,这样组件的可复用性提高了。
- 注意在传参数时候,如果写成isShow="true" 那么这是一个字符串 如果写成isShow={true} 这个 是布尔值
- {...对象} 展开赋值
- 默认属性值
- 属性验证
import React, { Component } from 'react';
import propsTypes from 'prop-types' // 引入检查类型
class Test extends Component {
static propTypes = { title:propsTypes.string } // 属性验证
render() {
return (
<div>
<h1>{title}</h1>
</div>
);
}
}
export default Test;
- 默认属性
import React, { Component } from 'react';
import propsTypes from 'prop-types' // 引入检查类型
class Test extends Component {
static defaultProps = { show:true } // 默认属性
render() {
return (
<div>
<h1>{title}</h1>
</div>
);
}
}
export default Test;
3. 属性VS状态
相似点:都是纯js对象,都会触发render更新,都具有确定性(状态/属性相同,结果相同)
不同点:
- 属性能从父组件获取,状态不能从父组件获取
- 属性可以由父组件修改,状态不能由父组件修改
- 属性能在内部设置默认值,状态也可以,设置方式不一样
- 属性不在组件内部修改,状态要在组件内部修改
- 属性能设置子组件初始值,状态不可以设置子组件初始值
- 属性可以修改子组件的值,状态不可以,state 的主要作用是用于组件保存、控制、修改自己的可变状态。
state 在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。可以认为 state 是一个局部的、只能被组件自身控制的数据源。 state 中状态可以通过 this.setState 方法进行更新,setState 会导致组件的重新渲染。
props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props ,否则组件的 props 永远保持不变。
没有 state 的组件叫无状态组件(stateless component),设置了 state 的叫做有状态组件 (stateful component)。因为状态会带来管理的复杂性,尽量多地写无状态组件,尽量少地写有状态的组件。这样会降低代码维护的难度,也会在一定程度上增强组件的可复用性。
数据渲染
- 条件渲染
<div>{show ? '显示' : '隐藏'}</div>
- 列表渲染
var list = ['1','2','3']
<div>
<li key={index}>{list}</li>
</div>
React的高效依赖于所谓的 Virtual-DOM,尽量不碰 DOM。对于列表元素来说会有一个问题:元素可能 会在一个列表中改变位置。要实现这个操作,只需要交换一下 DOM 位置就行了,但是 React 并不知道 其实我们只是改变了元素的位置,所以它会重新渲染后面两个元素(再执行 Virtual-DOM ),这样会大 大增加 DOM 操作。但如果给每个元素加上唯一的标识,React 就可以知道这两个元素只是交换了位 置,这个标识就是 key ,这个 key 必须是每个元素唯一的标识
一个简易的 todolist 案例:
import React, { Component } from 'react';
class Test extends Component {
constructor(){
super()
this.state = {
list: [
{
text:'吃饭'
},
{
text:'睡觉'
}
]
}
}
refInput = React.createRef()
handleAdd = () => {
this.state.list.push({ text:this.refInput.current.value})
this.setState({
list:this.state.list
})
this.refInput.current.value = '' // 清空输入框
}
handleDel = (index) => {
this.state.list.splice(index,1)
this.setState({
list:this.state.list
})
}
render() {
return (
<div>
<input ref={this.refInput}/>
<button onClick={this.handleAdd}>添加</button>
<ul>
{
this.state.list.map((item,index)=>{
return <li key={index}>{item.text}
<button onClick={() => this.handleDel(index)}>删除</button>
</li>
})
}
{
this.state.list.length === 0 ? <h3 style={{color: 'red'}}>暂无数据</h3> : null
}
</ul>
</div>
);
}
}
export default Test;
- @Title: React 基础笔记 02
- @Content: React
- @Autor: ling.wang
- @StudyDate: 2022-04-05、2022-04-10
- @WritingDate: 2022-04-05、2022-04-10