我有两个组件。 1 是一个钩子,第二个是映射元素数组并渲染它们的功能组件。
这是 useRooms 挂钩中的代码:
import { useCallback, useEffect, useState } from "react";
import { IRoom } from "@types";
import methods from "@api:methods";
import { useStoreState } from "../store.tsx";
const useRooms = (id: number) => {
const setState = useStoreState()[1];
const [loading, setLoading] = useState(true);
const [rooms, setList] = useState<IRoom[]>([]);
const addRoom = (room: IRoom) => {
setList((prevState) => [room, ...prevState]);
};
useEffect(() => {
setState((prevState) => ({ ...prevState, addRoom }));
}, []);
const handleRefresh = useCallback(
async (startLoading?: boolean) => {
if (startLoading) setLoading(true);
const data = await methods.service.rooms.list(id);
setLoading(false);
if (!data) {
return false;
}
setList(data);
},
[setList, id]
);
useEffect(() => {
setList([]);
handleRefresh(true).then();
}, [id]);
const handleCreate = useCallback(
async (name: string) => {
setLoading(true);
const data = await methods.service.rooms.add(id, name);
setLoading(false);
if (!data) {
console.error("Помилка", "Не вдалося створити точку");
setLoading(false);
return false;
} else {
setList((prevRooms) => {
const updatedRooms = [data, ...prevRooms];
console.log("Updated Rooms in useRooms:", updatedRooms);
console.log(
"Previous Rooms Reference:",
prevRooms === updatedRooms
);
return updatedRooms;
});
return data;
}
},
[id]
);
return {
loading,
handleRefresh,
rooms,
handleCreate,
};
};
export default useRooms;
当我添加一个新房间时,它会触发handleCreate回调,并在其中我在setList中设置新的房间数组,因此“房间”正在更新。
const handleCreate = useCallback(
async (name: string) => {
setLoading(true);
const data = await methods.service.rooms.add(id, name);
setLoading(false);
if (!data) {
console.error("Помилка", "Не вдалося створити точку");
setLoading(false);
return false;
} else {
setList((prevRooms) => {
const updatedRooms = [data, ...prevRooms];
console.log("Updated Rooms in useRooms:", updatedRooms);
console.log(
"Previous Rooms Reference:",
prevRooms === updatedRooms
);
return updatedRooms;
});
return data;
}
},
[id]
);
但不会触发使用该hook的List功能组件的重新渲染。为什么会这样?
import { FC, useEffect } from "react";
import styled from "styled-components";
import { token } from "@atlaskit/tokens";
import Spinner from "@atlaskit/spinner";
import useRooms from "../../hooks/useRooms.tsx";
import { useLocalState } from "../../store.tsx";
import Room from "./Room.tsx";
const List: FC = () => {
const { object } = useLocalState();
const { rooms, loading } = useRooms(object.id);
useEffect(() => {
console.log(rooms);
}, [rooms]);
return (
<Container>
<HeaderContainer>
{loading ? (
<Spinner size={"large"} />
) : (
<HeadTitle>{rooms.length} комнат</HeadTitle>
)}
</HeaderContainer>
<ListContainer>
{rooms.map((room) => (
<Room key={room.id} room={room} />
))}
</ListContainer>
</Container>
);
};
const Container = styled.div`
display: flex;
flex-direction: column;
border: 1px solid ${token("color.border")};
border-radius: 6px;
`;
const HeaderContainer = styled.div`
padding: 12px 13px;
box-sizing: border-box;
border-bottom: 1px solid ${token("color.border")};
`;
const HeadTitle = styled.span`
font-size: 14px;
font-weight: 500;
`;
const ListContainer = styled.div`
overflow-y: auto;
& > :not(:last-child) {
border-bottom: 1px solid ${token("color.border")};
}
`;
export default List;
您面临的问题可能与您在 useRooms 挂钩中更新房间状态的方式有关。当您使用新数组调用 setList 时,React 不会自动触发使用此钩子的组件的重新渲染。 为了确保 List 组件在房间状态发生变化时重新渲染,您可以尝试以下操作:
当房间状态发生变化时,使用 useEffect 钩子触发重新渲染:
然后喜欢 常量列表: FC = () => {
const { object } = useLocalState();
const { rooms, loading } = useRooms(object.id);
useEffect(() => {
console.log(rooms);
}, [rooms]);
return (
// ...
);