最近在学习 React ,还在 CRUD 阶段,目前遇到一个问题,没找到什么原因,还望大佬们指点一二
主要的问题就是我每次刷新页面,projects 和 users 接口都被调用了两次
嵌套结构是 <App> <ProjectListPage> </App>
以下是 ProjectListPage 组件的代码,只有这个组件有处理各种状态,其他两个组件 SeachPanel 、List 都没有状态的处理
import React, {useEffect, useState} from "react";
import {SeachPanel} from "./search-panel";
import {List} from "./list";
import {cleanObject, uesMount} from "../../utils";
import qs from "qs";
const apiUrl = 'http://localhost:3001'
export const ProjectListPage = () =>{
const [param,setParam] = useState({
name: '',
personId: ''
})
const [list,setList] = useState([])
// 当搜索内容改变的时候从新获取列表(默认会先执行一次)
useEffect(()=>{
fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(param))}`).then(async (resp) => {
if (resp.ok) {
setList(await resp.json())
}
})
},[])
// option 用户状态
const [users,setUsers] = useState([])
useEffect(()=>{
fetch(`${apiUrl}/users`).then(async (resp) => {
if (resp.ok) {
setUsers(await resp.json())
}
})
},[])
return <div>
<SeachPanel users={users} param={param} setParam={setParam}/>
<List users={users} list={list}/>
</div>
}
1
Satelli 2023-03-05 18:08:45 +08:00 2
|
2
Leviathann 2023-03-05 18:10:22 +08:00 2
strictMode 默认行为就是在开发模式下调用两次 useEffect
意思就是仅调用一次并不是 useEffect 定义的行为,只是目前是这么实现的,以后可能会改 调用两次的目的就是让你不要依赖 useEffect 的行为,而是显式声明一个标记值,根据标记值决定是否要执行 |
3
Parker0 OP |
4
huijiewei 2023-03-05 19:43:31 +08:00
用 swr
|
5
beginor 2023-03-05 19:50:47 +08:00 via Android 3
建议结合 react-router , 把加载数据 /保存数据之类的操作都写在路由的 loader 和 action 里面,jsx 只做界面, 这样逻辑清晰很多, 可以看下 react-router 官方的 tutorial
https://reactrouter.com/en/main/start/tutorial |
6
july1995 2023-03-05 22:59:16 +08:00 via iPhone
2 楼正解
|
8
sjhhjx0122 2023-03-05 23:20:07 +08:00
后面 react 应该会出个叫 use 的 api 配合 Suspense 就不需要在 useEffect 里发请求了
|
9
beginor 2023-03-05 23:49:13 +08:00
@sjhhjx0122 使用新版本 react-router 中的 data router , 已经不需要在 useEffect 中发送请求了
|
11
himself65 2023-03-06 03:32:20 +08:00 via iPhone
React 18.3.0 出了 OffScreen 组件之后,useEffect 不再保证空 deps 下只调用一次了,StrictMode 就是让告诉你不要瞎用这个 hook
|
12
yikyo 2023-03-06 05:11:17 +08:00 via iPhone
react 心智负担重,开发环境还要强制执行两次
第二个要吐槽 react router 每次版本更新就是破环性更新,一个路由库更新策略很奇怪,准备换 tanstack router |
13
hengshenyu 2023-03-06 08:30:28 +08:00
这儿实际是需要在下次执行 effect 的时候需要 AbortController 取消上一次的接口处理,需要大量的模板,不用请求库麻烦的很
|
14
ibegyourpardon 2023-03-06 09:22:49 +08:00
不使用 react-router ,使用状态管理如 zustand 之类,把数据获取和对数据的二次加工等放进去也是个不错的选择。
|