У меня есть два компонента. 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([]);
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]
);
Но это не вызывает повторную отрисовку функционального компонента 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 (
{loading ? (
) : (
{rooms.length} комнат
)}
{rooms.map((room) => (
))}
);
};
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;
Подробнее здесь: https://stackoverflow.com/questions/793 ... r-setstate