
最近在学习 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 bsfx2 2023-03-05 18:08:45 +08:00 |
2 Leviathann 2023-03-05 18:10:22 +08:00 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 建议结合 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 linkopeneyes 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 之类,把数据获取和对数据的二次加工等放进去也是个不错的选择。 |