react-async-states
Version:
A low-level multi paradigm state management library
50 lines (47 loc) • 2.73 kB
JavaScript
import * as React from 'react';
import { Context } from '../provider/context.js';
import { parseConfig } from './modules/HookResolveConfig.js';
import { useRetainInstance } from './modules/HookSubscription.js';
import { commit, autoRunAndSubscribeEvents } from './modules/HookSubscriptionCommit.js';
import { beginRender } from './modules/HookSubscriptionRender.js';
import { __DEV__ } from '../shared/index.js';
import { __DEV__warnInDevAboutIncompatibleConfig } from './modules/HookSubscriptionUtils.js';
// this is the main hook, useAsyncState previously
function useAsync_internal(options, deps, overrides) {
// only parse the configuration when deps change
// this process will yield the instance to subscribe to, along with
// the combined config (options)
let currentContext = React.useContext(Context);
let depsToUse = deps.concat(currentContext);
let { instance, config } = React.useMemo(() => parseConfig(currentContext, options, overrides), depsToUse);
// here, we will create a subscription from this component
// to this state instance. refer to HookSubscription type.
let subscription = useRetainInstance(instance, config, depsToUse);
if (__DEV__) {
__DEV__warnInDevAboutIncompatibleConfig(subscription);
}
// the alternate is similar to React alternate object that's
// created for every render and every fiber. It represents the
// work in progress essential information that will be flushed
// at the commit phase. It is important not to touch anything during
// render and port everything to the commit phase.
// a "null" alternate means that the render was bailed out.
let alternate = beginRender(subscription, config, depsToUse);
// this first effect will flush the alternate's properties inside
// the subscription, such as the current return, the parsed config...
// it is important to perform this work every time the alternate changes.
// if your state changes often, this effect may be executed everytime.
React.useLayoutEffect(() => commit(subscription, alternate), [alternate]);
// this second effect which is governed by the user's dependencies will:
// - subscribe to the state instance for changes
// - invoke onSubscribe events
// - run the state instance
React.useEffect(() => autoRunAndSubscribeEvents(subscription), depsToUse);
// the alternate may be null when we render the first time or when we bail out
// the render afterward.
// the returned priority is obviously for the alternate
let returnedSubscription = alternate ?? subscription;
return returnedSubscription.return;
}
export { useAsync_internal };
//# sourceMappingURL=useAsync_internal.js.map