React从服务端取数传递给子组件问题咨询(useEffect、useLayoutEffect相关)
问题1解答
- 首先纠正对钩子执行时机的认知错误:
useLayoutEffect是在DOM更新完成后、浏览器绘制屏幕前 同步执行 的,你所说的「屏幕全部绘制完成后才执行」是useEffect的特性,你记混了两个钩子的执行顺序。 - 你的场景是异步拉取服务端数据,不管用
useLayoutEffect还是useEffect都不可能在首次渲染前拿到接口返回结果,网络请求是异步操作,不会阻塞组件渲染。推荐方案如下:- 用普通
useEffect做数据拉取即可,完全没必要使用useLayoutEffect,这个钩子仅适用于需要同步修改DOM避免页面闪烁的特殊场景,不适合用来做数据请求 - 给组件加加载态判断,数据未返回时展示加载提示,返回后再渲染对应的子组件,避免空值报错
- 用普通
问题2解答
- 打印结果为
Promise<pending>是因为getAllUserList返回的是Promise对象,你没有等待Promise状态变更就直接将它赋值给了状态,需要通过.then或者async/await拿到接口实际返回的JSON数据后再更新状态。
修复后的代码示例
AdminContainer.js
import React, { useEffect, useState } from "react"; import { getAllUserList } from "../service/ApiService"; import DisplayUser from "./DisplayUser"; const AdminContainer = () => { const [allUsers, setUsers] = useState([]); const [loading, setLoading] = useState(true); useEffect (() => { // 通过.then处理异步返回的结果 getAllUserList() .then(userList => { setUsers(userList); }) .catch(err => { console.error("拉取用户列表失败:", err) }) .finally(() => { setLoading(false); }) }, []); // 加载态展示 if(loading) return <div>数据加载中...</div> return ( <div> {/* 批量渲染用户列表 */} {allUsers.map((user, i) => { return <DisplayUser inputUser={user} key={i} /> })} </div> ) } export default AdminContainer;
DisplayUser.js
import React, { useState, useEffect } from "react"; // 注意要解构props,否则你拿到的inputUser是整个props对象 const DisplayUser = ({inputUser}) => { const [user, setUser] = useState(inputUser); // 把inputUser加入依赖数组,父组件传值变化时自动更新 useEffect(() => { setUser(inputUser); }, [inputUser]) return ( <div> 用户名:{user?.username || '无数据'} </div> ) } export default DisplayUser;
额外注意点
ApiService.js中getAllUserList方法调用的接口路径写为了/auth/getAllUerList,存在拼写错误,少写了User里的s,正确路径应为/auth/getAllUserList,否则会请求404。
内容的提问来源于stack exchange,提问作者user5740635
相关产品推荐
相关产品推荐

