State在组件式编程里的基本用处
state是一个组件所包含的状态信息,所谓“状态”,就是该组件任意时刻都存放的各种数据。 state最重要的一点就是,当组件更新state时,会触发组件的重新渲染,可以认为发生了局部刷新。例如,希望在组件的div标签里显示一些动态变化的数据时,如果把这些数据作为全局变量存放,那么即便更新了这些变量,组件原先显示的数据仍然不会变,这就是因为组件并未进行重新渲染。
函数式组件的useState()
我们上手react时用的最多的就是类式组件。不过,类式组件定义和使用state虽然十分清晰,但有时其代码可能并不十分好写。尤其是我们在学习使用一些现成的图形库时,例如Antd、Antv,官方对于一些实用功能的实现全部是使用函数式组件编写的,强行将代码转成类式组件时间成本会较高。那么函数式组件如何定义和使用组件的state呢?
初始化state
类式组件中初始化state时可以直接写一句
state = {
key1: ... ,
key2: ...
}
进而完成类式组件state的初始化。
useState() 函数相对来讲更像是单独去针对每一个key去进行操控。例如,我们在组件中这样编码:
Child.js
import React, {useState} from "react";
const Child = () => {
// 设置一个state属性content,初始值是字符串‘初始状态’
// 初始值其实可以是任意类型的变量,包括字符串、boolean、列表、字典对象等等
const [content] = useState('初始状态')
return (
<div>
{content}
</div>
)
}
export default Child
那么我们在主页面APP.js中挂载组件Child,会获得其基本的展示:
更新state
在函数式组件中更新state应尽量按照规范调用setAttr:
import React, {useState} from "react";
const Child = () => {
// 例如,我的属性名叫content,那么调用其set函数时尽量命名为setContent。当然,叫别的也没问题,但不太规范
const [content, setContent] = useState('初始状态')
return (
// 也可以调用函数进而调用setContent,给set函数传递的参数就是你想要对其进行更新的值
<div onClick={()=>{
content==='初始状态' ? setContent('新的状态') : setContent('初始状态')
}}
>
</div>
)
}
export default Child
那么会获得如下效果:
通过函数回调进行state初始化
有时我们确实希望在组件刚刚加载时才进行state初始化,例如,加载一个数据列表,但是数据列表是需要向后端请求获取的,此时就会有几种思路:
- 如果是由于父组件点击了什么按钮进入或渲染了这个子组件,倒不如直接在父组件写好函数先把数据获取下来,随后更新父组件状态并把这些数据以props参数传给子组件
- 子组件以类式组件定义,在ComponentDidMount()里执行数据获取并setState() (极不推荐!这会导致两次子组件挂载)
- 子组件函数式组件定义,提前定义好getData函数,直接返回获取到的data 针对函数式组件,我确实曾经采用过第三点Tip。
大致编码方式如下:
Child.js
import axios from "axios";
import React, {useState} from "react";
const Child = () => {
const getInit = () => {
axios(url='xxxx', method='POST', 其他属性...).then(
request=>{
得到服务器响应怎么处理
return request.data
},
error=>{
alert(error)
return 一些自定义的错误信息
}
)
}
const [content, setContent] = useState(getInit)
return (
// 也可以调用函数进而调用setContent,给set函数传递的参数就是你想要对其进行更新的值
<div>
{content}
</div>
)
}
export default Child