trying out initializeState

This commit is contained in:
Michael Peters 2022-10-23 14:11:26 -07:00
parent 6e4a87b528
commit c0d535f1b0
6 changed files with 80 additions and 41 deletions

View File

@ -0,0 +1,32 @@
import * as electronRemote from '@electron/remote';
const electronConsole = electronRemote.getGlobal('console') as Console;
import Logger from '../../../../logger/logger';
const LOG = Logger.create(__filename, electronConsole);
import { useEffect, useSyncExternalStore } from 'react';
import { atom, useSetRecoilState } from 'recoil';
export const exampleState = atom<number>({
key: 'exampleState',
default: 4,
});
export function useExampleStateSubscription() {
LOG.debug('using');
const setExample = useSetRecoilState(exampleState);
const value = useSyncExternalStore(
() => {
LOG.debug('subscribing');
return () => {
LOG.debug('unsubscribing')
};
},
() => {
LOG.debug('returning');
return 6;
},
);
useEffect(() => {
setExample(value);
}, [setExample, value])
}

View File

@ -0,0 +1,18 @@
import React, { FC, ReactNode } from "react";
import { useRecoilValue } from "recoil";
import { overlayState } from "./require/atoms";
import GuildsManagerElement from "./sections/guilds-manager";
import TitleBar from "./sections/title-bar";
const App: FC = () => {
const overlay = useRecoilValue<ReactNode>(overlayState);
return (
<div>
<TitleBar />
<GuildsManagerElement />
<div className="react-overlays">{overlay}</div>
</div>
);
}
export default App;

View File

@ -14,6 +14,7 @@ import {
selector,
selectorFamily,
useRecoilState,
useRecoilValue,
useSetRecoilState,
} from 'recoil';
import {
@ -57,15 +58,16 @@ import {
useRecoilValueLoadableOrElse,
} from './atoms-funcs';
import { randomUUID } from 'crypto';
import assert from 'assert';
export const overlayState = atom<ReactNode>({
key: 'overlayState',
default: null,
});
export const guildsManagerState = atom<GuildsManager | null>({
export const guildsManagerState = atom<GuildsManager>({
key: 'guildsManager',
default: null,
default: null as unknown as GuildsManager, // this will be set by initializeState
// allow mutability so that we can have changes to internal guild stuff
// we will still listen to new/update/delete/conflict events to maintain the UI's state
@ -88,7 +90,7 @@ export const guildMetaState = atomFamily<LoadableValue<GuildMetadata>, number>({
guildDataSubscriptionLoadableSingleEffect(
guildId,
async (guild: CombinedGuild) => {
LOG.debug('fetching guild metadata', { guild });
LOG.debug('fetching guild metadata');
return await guild.fetchMetadata();
},
{
@ -548,15 +550,13 @@ export function useRecoilValueSoftImgSrc(recoilValue: RecoilValue<string>): stri
}
// initialize with a guildsManager
export function useInitRecoil(guildsManager: GuildsManager) {
export function useInitRecoil() {
const guildsManager = useRecoilValue(guildsManagerState);
assert(guildsManager !== null);
LOG.debug(`recoil init, gm has ${guildsManager.guilds.length} guilds`);
const setGuildsManager = useSetRecoilState(guildsManagerState);
const setGuilds = useSetRecoilState(allGuildsState);
const [currGuildId, setCurrGuildId] = useRecoilState(currGuildIdState);
useEffect(() => {
LOG.debug(`setting guildsManager to ${guildsManager?.guilds.length}`);
setGuildsManager(guildsManager);
}, [guildsManager, setGuildsManager]);
useEffect(() => {
const updateGuilds = () => {
setGuilds(guildsManager.guilds.slice());

View File

@ -1,28 +1,11 @@
import React, { FC, ReactNode } from 'react';
import { useRecoilValue } from 'recoil';
import GuildsManager from '../guilds-manager';
import { useInitRecoil, overlayState } from './require/atoms';
import GuildsManagerElement from './sections/guilds-manager';
import TitleBar from './sections/title-bar';
import React, { FC } from 'react';
import { useInitRecoil } from './require/atoms';
import App from './app';
export interface RootElementProps {
guildsManager: GuildsManager;
}
const RootElement: FC = () => {
useInitRecoil();
const RootElement: FC<RootElementProps> = (props: RootElementProps) => {
const { guildsManager } = props;
useInitRecoil(guildsManager);
const overlay = useRecoilValue<ReactNode>(overlayState);
return (
<div>
<TitleBar />
<GuildsManagerElement />
<div className="react-overlays">{overlay}</div>
</div>
);
return <App />
};
export default RootElement;

View File

@ -28,12 +28,12 @@ const GuildElement: FC = () => {
const activeChannel = useRecoilValue(currGuildActiveChannelState);
const setActiveChannelId = useSetRecoilState(guildActiveChannelIdState(guild?.id ?? -1));
useEffect(() => {
LOG.debug('guild changed', { guildId: guild?.id ?? '<null>' });
}, [ guild ]);
useEffect(() => {
LOG.debug('self member changed', { selfMember });
}, [ selfMember ]);
//useEffect(() => {
// lOG.debug('guild changed', { guildId: guild?.id ?? '<null>' });
//}, [ guild ]);
//useEffect(() => {
// lOG.debug('self member changed', { selfMember });
//}, [ selfMember ]);
// useEffect(() => {
// lOG.debug('active channel changed', { activeChannel });
// }, [ activeChannel ])

View File

@ -18,7 +18,8 @@ import ResourceRAMCache from './resource-ram-cache';
import { createRoot } from 'react-dom/client';
import React from 'react';
import RootElement from './elements/root';
import { RecoilRoot } from 'recoil';
import { MutableSnapshot, RecoilRoot } from 'recoil';
import { guildsManagerState } from './elements/require/atoms';
LOG.silly('modules loaded');
@ -59,10 +60,15 @@ window.addEventListener('DOMContentLoaded', () => {
LOG.silly('guildsManager initialized');
// TODO: Try using initializeState from recoilRoot
// https://recoiljs.org/docs/api-reference/core/RecoilRoot/
const root = createRoot(document.getElementById('react-root')!);
function initializeState({ set }: MutableSnapshot): void {
set(guildsManagerState, guildsManager);
}
root.render(
<RecoilRoot>
<RootElement guildsManager={guildsManager} />
<RecoilRoot initializeState={initializeState}>
<RootElement />
</RecoilRoot>,
);
})();