本篇内容主要讲解“React如何使用useEffect解决setState副作用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React如何使用useEffect解决setState副作用”吧!
我们会用到一个很简单的资源API,https://swapi.dev/api/people/1
,这是一个会返回星球大战里的人物信息的API。
所以我们要做的事:1、读取API中提供的数据; 2、将获得的数据写入state。
首先我们来做第一步,这里介绍一下fetch()
fetch()
必须接受一个参数——资源的路径。无论请求成功与否,它都返回一个 Promise 对象,resolve 对应请求的Response。
一旦 Response被返回,就可以使用一些方法来定义内容的形式
所以我们可以使用以下代码完成资源API的读取,并且渲染到页面上
import React from "react" export default function App() { const [starWarsData, setStarWarsData] = React.useState({}) fetch("https://swapi.dev/api/people/1") .then(res => res.json()) .then(data => setStarWarsData(data)) return ( <div> <pre>{JSON.stringify(starWarsData, null, 2)}</pre> </div> ) }
可以看到我们似乎确实轻松地获得了资源接口所提供给我们的数据
然而当我们加上控制台的输出后,事情就变得不一样了
在这个程序中,我们可以加上一句console.log
在控制台输出后天的运行情况,如下
import React from "react" export default function App() { const [starWarsData, setStarWarsData] = React.useState({}) console.log("component rendered") fetch("https://swapi.dev/api/people/1") .then(res => res.json()) .then(data => setStarWarsData(data)) return ( <div> <pre>{JSON.stringify(starWarsData, null, 2)}</pre> </div> ) }
这时再运行就能清楚地看到在控制台处显示了这个组件在一直不断地生成,重新地render
我们可以简单地分析一下原因,
组件每次render都会触发一次fetch,
然后fetch获取的数据传入setState又会重新使得组件被render一遍,
而这就形成了一个死循环,致使组件不断地生成。
在useEffect()
出现之前,react并没有setState后停止render的方法,这就使得setState的使用需要非常谨慎,不过如今提供了useEffet()
来解决这个问题
useEffect接受两个参数,其中第二个参数是可选的
useEffect(<function>, <dependency array>)
所以让我们先来尝试一下不使用第二个参数会得到什么结果
import React from "react" export default function App() { const [starWarsData, setStarWarsData] = React.useState({}) console.log("component rendered") React.useEffect(function(){ fetch("https://swapi.dev/api/people/1") .then(res => res.json()) .then(data => setStarWarsData(data)) }) return ( <div> <pre>{JSON.stringify(starWarsData, null, 2)}</pre> </div> ) }
可以看到在上面的代码里我们已经按照语法要求使用了useEffect()
,然而结果却不如我们所设想的只打印一条语句,依旧是一个死循环
原因在于只使用一个参数的useEffect()
的效果是在组件被挂载
和被更新
两种情况下执行参数的函数,所以并不能解决更新状态不执行的效果
那么就要用到第二个参数了,第二个参数叫做dependency array
,只有在这个数组里的元素更新了,才会触发这个useEffect
所以这里我们可以将第二个参数设置为一个空数组,这样只有在组件刚刚被挂载的时候才会执行useEffect
,很好的解决了我们只需要读取一遍API的任务要求
import React from "react" export default function App() { const [starWarsData, setStarWarsData] = React.useState({}) console.log("component rendered") React.useEffect(function(){ fetch("https://swapi.dev/api/people/1") .then(res => res.json()) .then(data => setStarWarsData(data)) }, []) return ( <div> <pre>{JSON.stringify(starWarsData, null, 2)}</pre> </div> ) }
由dependency array
我们也可以得出另一种用法,可以看以下代码
import React from "react" export default function App() { const [count, setCount] = React.useState(0) console.log("Component rendered") React.useEffect(() => { console.log("Effect function ran") }, [count]) return ( <div> <h3>The count is {count}</h3> <button onClick={() => setCount(prevCount => prevCount + 1)}>Add</button> </div> ) }
我们在第二个参数处填入了会随着我们点击而变化的count
,所以在我们每次点击使得count
增加以后,count state
发生变化,执行useEffect
第一个参数的函数
可以看到设置了count state
,再在useEffect
中设置count
为dependency
,这样每次改变count的值就会再一次执行useEffect中的函数。
到此,相信大家对“React如何使用useEffect解决setState副作用”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。