React Redux添加好友功能报错:friends.find/map不是函数求助
解决添加好友功能中的TypeError: friends.find/map is not a function错误
问题场景
开发添加好友功能时,点击「添加好友」按钮触发错误:TypeError: friends.find is not a function。在Friend.jsx中添加一段标记为Error的代码后,错误变为friends.map is not a function(错误出现在friendsList.jsx组件)。
相关代码
Friend.jsx组件
import { PersonAddOutlined, PersonRemoveOutlined } from "@mui/icons-material"; import { Box, Divider, IconButton, Typography, useTheme } from "@mui/material"; import { useDispatch, useSelector } from "react-redux"; import { setFriends } from "state"; import FlexBetween from "./FlexBetween"; import UserImage from "./UserImage"; import { useNavigate } from "react-router-dom"; const Friend = ({ friendId, name, subtitle, userPicturePath }) => { const dispatch = useDispatch(); const navigate = useNavigate(); const { _id } = useSelector((state) => state.user); const token = useSelector((state) => state.token); const friends = useSelector((state) => state.user.friends); // if (!Array.isArray(friends)) { | // return console.log(friends); |<=== Error // } | // eslint-disable-next-line react-hooks/rules-of-hooks const { palette } = useTheme(); const primaryLight = palette.primary.light; const primaryDark = palette.primary.dark; const main = palette.neutral.main; const medium = palette.neutral.medium; const isFriend = friends.find((friend) => friend._id === friendId); const patchFriend = async() => { const response = await fetch( `http://localhost:3001/users/${_id}/${friendId}`, { method: "PATCH", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }, } ); const data = await response.json(); dispatch(setFriends({ friends: data })); // console.log("array123: ",Array.isArray(friends)) // console.log("array123: ") }; return ( <FlexBetween> <FlexBetween gap="1rem"> <UserImage image={userPicturePath} size="55px" /> <Box onClick={() => { navigate(`/profile/${friendId}`); navigate(0); }} > <Typography color={main} variant="h5" fontWeight="500" sx={{ "&:hover": { color: palette.primary.light, cursor: "pointer" } }} > {name} </Typography> <Typography color={medium} fontSize="0.75rem"> {subtitle} </Typography> </Box> </FlexBetween> <IconButton onClick={() => patchFriend()} sx={{ backgroundColor: primaryLight, p: "0.6rem" }} > {isFriend ? ( <PersonRemoveOutlined sx={{ color: primaryDark }} /> ) : ( <PersonAddOutlined sx={{ color: primaryDark }} /> )} </IconButton> </FlexBetween> ) }; export default Friend;
state.js代码
import { createSlice } from "@reduxjs/toolkit"; const initialState = { mode: "light", user: null, token: null, posts: [], }; export const authSlice = createSlice({ name: "auth", initialState, reducers: { setLogin: (state, action) => { state.user = action.payload.user; state.token = action.payload.token; }, setLogout: (state) => { state.user = null; state.token = null; }, setFriends: (state, action) => { if (state.user) { state.user.friends = action.payload.friends; } else { console.error("user friends is not exist") } }, setPosts: (state, action) => { state.posts = action.payload.posts; }, setPost: (state, action) => { const updatedPosts = state.posts.map((post) => { if (post._id === action.payload.post._id) return action.payload.post; return post; }); state.posts = updatedPosts; }, }, }); export const { setLogin, setLogout, setFriends, setPosts, setPost } = authSlice.actions; export default authSlice.reducer;
问题原因
核心问题是**friends变量并非数组类型**,导致无法调用数组方法find和map,具体诱因:
- Redux初始状态中
state.user为null,state.user.friends未被初始化为数组;若登录后后端返回的用户数据中friends字段不是数组,也会引发异常。 - PATCH请求后直接将后端返回的
data赋值给state.user.friends,若后端返回的data结构不是数组(比如是包含friends的对象),会导致friends变为非数组类型。 - 注释中的Error代码块违反React Hooks规则(在
useTheme调用前提前返回),引发组件渲染异常。
解决方案
1. 初始化Redux状态为数组
修改state.js的initialState,确保user默认包含空数组的friends:
const initialState = { mode: "light", user: { friends: [] }, // 替换null为包含空friends数组的对象 token: null, posts: [], };
或者在setLogin时补全friends数组:
setLogin: (state, action) => { state.user = { ...action.payload.user, friends: action.payload.user.friends || [] }; state.token = action.payload.token; },
2. 校验后端返回数据格式
检查PATCH接口的返回结构,若后端返回的是{ friends: [...] }格式的对象,修改patchFriend中的dispatch逻辑:
const data = await response.json(); dispatch(setFriends({ friends: data.friends })); // 取data中的friends数组,而非直接传data
3. 组件中添加默认值保障
在获取friends时添加可选链和默认值,避免null/undefined:
const friends = useSelector((state) => state.user?.friends || []);
4. 移除违规的Error代码块
删除Friend.jsx中那段注释的Error代码,它违反了React Hooks的调用顺序规则(必须在组件顶层按顺序调用,不能在条件判断后提前返回)。
内容的提问来源于stack exchange,提问作者Phoenix Phoenix
相关产品推荐
相关产品推荐

