Почему не происходит ререндер компонента в React?

Описание

Есть компоненты: A, B, C

Компонент А:

export default function A() {
  const [activeConversationId, setActiveConversationId] = useState<string>("");

  return (
  <>
            <B
              activeConversationId={activeConversationId}
            />
            
            {!activeConversationId && <C onClickNew={(conversationId) => setActiveConversationId(conversationId)} />}
   </>
  );

Компонент B:

export default function B({ activeConversationId }) {
  const { conversations = [] } = useConversations();


useEffect(() => {
  console.log('CONVERSATION LIST', conversations);
}, [conversations]);
  
  return (
    <>
      {conversations.map((conversation) => (
        <Group key={conversation.id} justify='space-between' style={{ marginRight: '5%' }} >
            {conversation.id}
        </Group>
      ))}
    </>
  );
}

Компонент C:

export default function C({ onClickNew }: IConversationNew) {
    const { db, write } = useLowDb();

    const [createConversationId, setCreateConversationId] = useState<boolean>(false);

    useEffect(() => {
        if (!(db && createConversationId)) {
            return;
        }

        const conversation: Conversation = { id: getRandomId(), messages: [] };

        console.log('NEW');
        
        db.conversation.push(conversation);
        write();

        onClickNew(conversation.id);
        setCreateConversationId(false);
    }, [createConversationId, db]);

    return (
    <>
       <Button
                size="xl"
                variant="outline"
                onClick={() => setCreateConversationId(true)}
            >
                <IconPlus size={48} />
            </Button>
     </>
    );
};

Также есть два кастомных хука:

useLowDb

export default function useLowDb() {
    const [loading, setLoading] = useState<boolean>(true);
    const [database, setDatabase] = useState<InitializedDb>();
    const [data, setData] = useState<InitData>();

    const getAPIData = async () => {
        setLoading(true);

        const database = await lowdbInstance.getDb();

        setDatabase(database);
        setData(database.data);

        setLoading(false);
    };

    useEffect(() => {
        getAPIData();
    }, []);

    const write = () => {
        if (!database) {
            return;
        }
        
        database?.write();
        setData(structuredClone(data));
        console.log('LOWDB', data?.conversation);
        
    };

    return {
        loading,
        db: data,
        write,
    };
}

useConversations:

export default function useConversations() {
    const { db } = useLowDb();

    const [loading, setLoading] = useState<boolean>(true);
    const [conversations, setConversations] = useState<Conversation[]>();

    useEffect(() => {
        setLoading(true);

        if (!db) {
            return;
        }

        
        setConversations(structuredClone(db.conversation));
        
console.log('CONVETSATION LIST', db.conversation);

        setLoading(false);
    }, [db]);

    return {
        loading,
        conversations,
    };
}

Идея такая:

  • Компонент А является родителем для B И C.
  • Компонент B рендерит список комнат из хука useConversations.
  • Компонент С Создает комнату и вызывает write у хука useLowDb().

Ожидаемое поведение:

Компонент С модифицирует useLowDb, что должно вызвать цепную реакцию, обновить useConversations, а он обновит компонент B. После этого выполнится {conversations.map((conversation) => ( в компоненте B. В результате в списке будет новая комната.

Реальная ситуация:

В компоненте B, в useEffect:

useEffect(() => {
  console.log('CONVERSATION LIST', conversations);
}, [conversations]);

Я вижу обновленные данные. Но {conversations.map((conversation) => ( не отрабатывает. И новая комната не рендерится.

В чем проблема?


Ответы (0 шт):