123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- import _extends from "@babel/runtime/helpers/esm/extends";
- import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
- const _excluded = ["reactReduxForwardedRef"];
- import hoistStatics from 'hoist-non-react-statics';
- import * as React from 'react';
- import { isValidElementType, isContextConsumer } from 'react-is';
- import defaultSelectorFactory from '../connect/selectorFactory';
- import { mapDispatchToPropsFactory } from '../connect/mapDispatchToProps';
- import { mapStateToPropsFactory } from '../connect/mapStateToProps';
- import { mergePropsFactory } from '../connect/mergeProps';
- import { createSubscription } from '../utils/Subscription';
- import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect';
- import shallowEqual from '../utils/shallowEqual';
- import warning from '../utils/warning';
- import { ReactReduxContext } from './Context';
- import { notInitialized } from '../utils/useSyncExternalStore';
- let useSyncExternalStore = notInitialized;
- export const initializeConnect = fn => {
- useSyncExternalStore = fn;
- };
- const EMPTY_ARRAY = [null, 0];
- const NO_SUBSCRIPTION_ARRAY = [null, null];
- const stringifyComponent = Comp => {
- try {
- return JSON.stringify(Comp);
- } catch (err) {
- return String(Comp);
- }
- };
- function useIsomorphicLayoutEffectWithArgs(effectFunc, effectArgs, dependencies) {
- useIsomorphicLayoutEffect(() => effectFunc(...effectArgs), dependencies);
- }
- function captureWrapperProps(lastWrapperProps, lastChildProps, renderIsScheduled, wrapperProps,
- childPropsFromStoreUpdate, notifyNestedSubs) {
-
- lastWrapperProps.current = wrapperProps;
- renderIsScheduled.current = false;
- if (childPropsFromStoreUpdate.current) {
- childPropsFromStoreUpdate.current = null;
- notifyNestedSubs();
- }
- }
- function subscribeUpdates(shouldHandleStateChanges, store, subscription, childPropsSelector, lastWrapperProps, lastChildProps, renderIsScheduled, isMounted, childPropsFromStoreUpdate, notifyNestedSubs,
- additionalSubscribeListener) {
-
- if (!shouldHandleStateChanges) return () => {};
- let didUnsubscribe = false;
- let lastThrownError = null;
- const checkForUpdates = () => {
- if (didUnsubscribe || !isMounted.current) {
-
-
- return;
- }
- const latestStoreState = store.getState();
- let newChildProps, error;
- try {
-
-
- newChildProps = childPropsSelector(latestStoreState, lastWrapperProps.current);
- } catch (e) {
- error = e;
- lastThrownError = e;
- }
- if (!error) {
- lastThrownError = null;
- }
- if (newChildProps === lastChildProps.current) {
- if (!renderIsScheduled.current) {
- notifyNestedSubs();
- }
- } else {
-
-
-
-
- lastChildProps.current = newChildProps;
- childPropsFromStoreUpdate.current = newChildProps;
- renderIsScheduled.current = true;
-
- additionalSubscribeListener();
- }
- };
- subscription.onStateChange = checkForUpdates;
- subscription.trySubscribe();
-
- checkForUpdates();
- const unsubscribeWrapper = () => {
- didUnsubscribe = true;
- subscription.tryUnsubscribe();
- subscription.onStateChange = null;
- if (lastThrownError) {
-
-
-
-
-
- throw lastThrownError;
- }
- };
- return unsubscribeWrapper;
- }
- const initStateUpdates = () => EMPTY_ARRAY;
- function strictEqual(a, b) {
- return a === b;
- }
- let hasWarnedAboutDeprecatedPureOption = false;
- function connect(mapStateToProps, mapDispatchToProps, mergeProps, {
-
-
- pure,
- areStatesEqual = strictEqual,
- areOwnPropsEqual = shallowEqual,
- areStatePropsEqual = shallowEqual,
- areMergedPropsEqual = shallowEqual,
-
- forwardRef = false,
-
- context = ReactReduxContext
- } = {}) {
- if (process.env.NODE_ENV !== 'production') {
- if (pure !== undefined && !hasWarnedAboutDeprecatedPureOption) {
- hasWarnedAboutDeprecatedPureOption = true;
- warning('The `pure` option has been removed. `connect` is now always a "pure/memoized" component');
- }
- }
- const Context = context;
- const initMapStateToProps = mapStateToPropsFactory(mapStateToProps);
- const initMapDispatchToProps = mapDispatchToPropsFactory(mapDispatchToProps);
- const initMergeProps = mergePropsFactory(mergeProps);
- const shouldHandleStateChanges = Boolean(mapStateToProps);
- const wrapWithConnect = WrappedComponent => {
- if (process.env.NODE_ENV !== 'production' && !isValidElementType(WrappedComponent)) {
- throw new Error(`You must pass a component to the function returned by connect. Instead received ${stringifyComponent(WrappedComponent)}`);
- }
- const wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
- const displayName = `Connect(${wrappedComponentName})`;
- const selectorFactoryOptions = {
- shouldHandleStateChanges,
- displayName,
- wrappedComponentName,
- WrappedComponent,
-
- initMapStateToProps,
-
- initMapDispatchToProps,
- initMergeProps,
- areStatesEqual,
- areStatePropsEqual,
- areOwnPropsEqual,
- areMergedPropsEqual
- };
- function ConnectFunction(props) {
- const [propsContext, reactReduxForwardedRef, wrapperProps] = React.useMemo(() => {
-
-
-
- const {
- reactReduxForwardedRef
- } = props,
- wrapperProps = _objectWithoutPropertiesLoose(props, _excluded);
- return [props.context, reactReduxForwardedRef, wrapperProps];
- }, [props]);
- const ContextToUse = React.useMemo(() => {
-
-
- return propsContext && propsContext.Consumer &&
- isContextConsumer( React.createElement(propsContext.Consumer, null)) ? propsContext : Context;
- }, [propsContext, Context]);
- const contextValue = React.useContext(ContextToUse);
-
-
- const didStoreComeFromProps = Boolean(props.store) && Boolean(props.store.getState) && Boolean(props.store.dispatch);
- const didStoreComeFromContext = Boolean(contextValue) && Boolean(contextValue.store);
- if (process.env.NODE_ENV !== 'production' && !didStoreComeFromProps && !didStoreComeFromContext) {
- throw new Error(`Could not find "store" in the context of ` + `"${displayName}". Either wrap the root component in a <Provider>, ` + `or pass a custom React context provider to <Provider> and the corresponding ` + `React context consumer to ${displayName} in connect options.`);
- }
- const store = didStoreComeFromProps ? props.store : contextValue.store;
- const getServerState = didStoreComeFromContext ? contextValue.getServerState : store.getState;
- const childPropsSelector = React.useMemo(() => {
-
-
- return defaultSelectorFactory(store.dispatch, selectorFactoryOptions);
- }, [store]);
- const [subscription, notifyNestedSubs] = React.useMemo(() => {
- if (!shouldHandleStateChanges) return NO_SUBSCRIPTION_ARRAY;
-
- const subscription = createSubscription(store, didStoreComeFromProps ? undefined : contextValue.subscription);
-
-
-
- const notifyNestedSubs = subscription.notifyNestedSubs.bind(subscription);
- return [subscription, notifyNestedSubs];
- }, [store, didStoreComeFromProps, contextValue]);
-
- const overriddenContextValue = React.useMemo(() => {
- if (didStoreComeFromProps) {
-
-
-
- return contextValue;
- }
-
- return _extends({}, contextValue, {
- subscription
- });
- }, [didStoreComeFromProps, contextValue, subscription]);
- const lastChildProps = React.useRef();
- const lastWrapperProps = React.useRef(wrapperProps);
- const childPropsFromStoreUpdate = React.useRef();
- const renderIsScheduled = React.useRef(false);
- const isProcessingDispatch = React.useRef(false);
- const isMounted = React.useRef(false);
- const latestSubscriptionCallbackError = React.useRef();
- useIsomorphicLayoutEffect(() => {
- isMounted.current = true;
- return () => {
- isMounted.current = false;
- };
- }, []);
- const actualChildPropsSelector = React.useMemo(() => {
- const selector = () => {
-
-
-
-
-
-
- if (childPropsFromStoreUpdate.current && wrapperProps === lastWrapperProps.current) {
- return childPropsFromStoreUpdate.current;
- }
-
-
-
- return childPropsSelector(store.getState(), wrapperProps);
- };
- return selector;
- }, [store, wrapperProps]);
-
-
- const subscribeForReact = React.useMemo(() => {
- const subscribe = reactListener => {
- if (!subscription) {
- return () => {};
- }
- return subscribeUpdates(shouldHandleStateChanges, store, subscription,
- childPropsSelector, lastWrapperProps, lastChildProps, renderIsScheduled, isMounted, childPropsFromStoreUpdate, notifyNestedSubs, reactListener);
- };
- return subscribe;
- }, [subscription]);
- useIsomorphicLayoutEffectWithArgs(captureWrapperProps, [lastWrapperProps, lastChildProps, renderIsScheduled, wrapperProps, childPropsFromStoreUpdate, notifyNestedSubs]);
- let actualChildProps;
- try {
- actualChildProps = useSyncExternalStore(
- subscribeForReact,
-
- actualChildPropsSelector, getServerState ? () => childPropsSelector(getServerState(), wrapperProps) : actualChildPropsSelector);
- } catch (err) {
- if (latestSubscriptionCallbackError.current) {
- ;
- err.message += `\nThe error may be correlated with this previous error:\n${latestSubscriptionCallbackError.current.stack}\n\n`;
- }
- throw err;
- }
- useIsomorphicLayoutEffect(() => {
- latestSubscriptionCallbackError.current = undefined;
- childPropsFromStoreUpdate.current = undefined;
- lastChildProps.current = actualChildProps;
- });
-
- const renderedWrappedComponent = React.useMemo(() => {
- return (
-
-
- React.createElement(WrappedComponent, _extends({}, actualChildProps, {
- ref: reactReduxForwardedRef
- }))
- );
- }, [reactReduxForwardedRef, WrappedComponent, actualChildProps]);
-
- const renderedChild = React.useMemo(() => {
- if (shouldHandleStateChanges) {
-
-
-
- return React.createElement(ContextToUse.Provider, {
- value: overriddenContextValue
- }, renderedWrappedComponent);
- }
- return renderedWrappedComponent;
- }, [ContextToUse, renderedWrappedComponent, overriddenContextValue]);
- return renderedChild;
- }
- const _Connect = React.memo(ConnectFunction);
-
- const Connect = _Connect;
- Connect.WrappedComponent = WrappedComponent;
- Connect.displayName = ConnectFunction.displayName = displayName;
- if (forwardRef) {
- const _forwarded = React.forwardRef(function forwardConnectRef(props, ref) {
-
- return React.createElement(Connect, _extends({}, props, {
- reactReduxForwardedRef: ref
- }));
- });
- const forwarded = _forwarded;
- forwarded.displayName = displayName;
- forwarded.WrappedComponent = WrappedComponent;
- return hoistStatics(forwarded, WrappedComponent);
- }
- return hoistStatics(Connect, WrappedComponent);
- };
- return wrapWithConnect;
- }
- export default connect;
|