react教程,函数式组件如何使用state?useState范例
发布于 作者:苏南大叔 来源:程序如此灵动~在前几天的文章里面,在叙述 react 的组件式编程的路由传参问题的时候,曾经使用过useParams
。那么,在本文中,将要使用的useState
来解决state
的问题。值得特别说明的是:本篇文章是在函数式组件里面使用state
,所以会和传统的react
类组件中使用this.state
状态机制有所不同。
大家好,这里是苏南大叔的“程序如此灵动”博客,这里记录苏南大叔和计算机代码的故事。在本文中,您将学习到react
的函数式组件的state
的使用方法。测试环境:win10
,node@16.14.2
,npm@8.3.0
,react@18.1.0
,react-dom@18.1.0
。
本文说的是函数式组件,如果想了解类式组件中state
的用法,请参考:
https://newsn.net/say/react-state.html如果您的状态设置比较复杂,可以考虑使用
useState
的升级版useReducer
:
https://newsn.net/say/react-usereducer.html
基本使用方式
本文的范例,是通过create-react-app
创建的,然后简单的对 app 函数式组件进行了修改。
import './App.css';
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0)
function incr() {
setCount(count + 1)
}
return (
<div className="App">
<header className="App-header">
{count}
<button onClick={incr}>+1</button>
</header>
</div>
);
}
export default App;
代码说明如下:
引入useState
:
import React, { useState } from 'react';
然后,定义一个useState
,是个非常奇怪的使用方式,
const [返回值,函数名] = useState(初始值)
注意:如果报错{函数名}不存在,那么请检查:等号左侧一定是中括号[]
,而不是大括号{}
。
如果需要控制的变量比较多的话,就需要多次定义useState()
。
const [count, setCount] = useState(0)
const [str, setStrByApi] = useState("")
或者把需要控制的变量,放到一个object
里面。(不推荐,因为改写就比较麻烦)。
let [info, setinfo] = useState({
name: '苏南大叔',
city: 'beijing'
})
setinfo({ ...info, city: 'tangshan' });
如果翻译成大家能够接受的代码的话【仅仅是个通俗的理解而已】,就是:
let state = {};
let count;
function setCountDefault(cnt){
if(!state.count){
setCount(cnt);
}
}
function setCount(cnt){
count = state.count = cnt;
}
setCountDefault(0); //第一次定义传入默认值
setCount(9); //第二次调用设置合适的值
这里传递的参数是初始值,也就是说:当已经有数据定义在state
里面的话,就不修改了。
题外话:使用ajax获取数据
因为在日常的使用过程中,都是使用ajax
的方式来获取数据的。目前的浏览器都内置fetch
的支持,react
又属于前端的范畴,所以默认也是可以使用fetch
函数的。
涉及到接口服务代码,见下面这篇文章:
代码如下:
const [str, setStrByApi] = useState("")
const [str2, setStr2ByApi] = useState("")
async function ajax() {
const response = await fetch('http://127.0.0.1:3222/hi/');
const str = await response.text();
setStrByApi(str);
fetch("http://127.0.0.1:3222/hello?f=me").then(function(response) {
return response.json();
}).then(function(data) {
setStr2ByApi(data["f"]);
})
.catch(function(e) {
});
}
在render
的时候,使用{str}
和{str2}
来显示变量。
这里需要注意的是:
如果使用await
方式的话,这里可能需要两个await
,然后还需要把对应函数设置为async
。当然还可以使用.then
的方式。
最终代码
react
最常见的情况,使用props
和state
,而props
就是组件的第一个参数,state
需要引入useState
,路由传参的话,需要引入useParams
。
最终代码如下:index.js
:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App pre="服务器端返回:" />
</React.StrictMode>
);
app.js
:
import './App.css';
import React, { useState } from 'react';
function App(props) {
const [count, setCount] = useState(0)
const [str, setStrByApi] = useState("")
const [str2, setStr2ByApi] = useState("")
async function ajax() {
// 双await
const response = await fetch('http://127.0.0.1:3222/hi/');
const str = await response.text();
setStrByApi(str);
// 或者.then方式
fetch("http://127.0.0.1:3222/hello?f=me").then(function(response) {
return response.json();
}).then(function(data) {
setStr2ByApi(data["f"]);
})
.catch(function(e) {
});
}
function incr() {
setCount(count + 1)
}
var pre = props.pre;
return (
<div className="App">
<header className="App-header">
{count},{pre}{str} {str2}
<button onClick={incr}>+1</button>
<button onClick={ajax}>ajax</button>
</header>
</div>
);
}
export default App;
运行效果:
三种写法
第一种情况写法简单,但是特殊情况下失效。
setCount(count + 1);
后面的两种方式,一直可用,特殊情况下有奇效。
setCount(count => count + 1);
setCount((count) =>{return count + 1;});
至于特殊情况,目前已知有setInterval()
,暂时留后续文章讨论。参考链接:
注意类型
能够作为useState()
观测的变量,必须是普通的变量类型,对象object
很有可能是不合适的。它无法做到深层测试比对。从而引发界面不刷新。
参考文献
综述
本文描述,在react
的函数式组件里面,如何使用state
以及props
。state
需要引入useState
,而props
需要调用函数式组件的第一个参数。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。