Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ideas for improving performance and design hooks reasons #1186

Closed
ivansky opened this issue Feb 13, 2019 · 2 comments
Closed

Ideas for improving performance and design hooks reasons #1186

ivansky opened this issue Feb 13, 2019 · 2 comments

Comments

@ivansky
Copy link

ivansky commented Feb 13, 2019

I've read The History and Implementation of React-Redux few days ago and I have several statements and questions:

  1. I do not want use context for performance reason (as in v6), let's not affect React flow after each action if it doesn't change anything.
  2. For the first statement I have question, is there any problem to subscribe on store inside single effect and call updates only when we have changes? Is it problem of making calls continuously depending on components tree?
  3. Do we actually need Provider?
  4. Looks like dispatching actions by action creator should work as useCallback and don't change anything at all.
  5. The implementation of state mapper should give us an ability to use our selectors without additional effort.

Passing store reference to actual components:

<ReduxStoreProvider store={ store }>
    // ...
</ReduxStoreProvider>

const ReduxUpdateLessContext = React.createContext(null);

function ReduxStoreProvider({ store }) {
   // Store object isn't changing? So let's pass only reference to it.
   // Don't affect react flow each action
   const storeReference = useRef(store);

   return (
      <ReduxUpdateLessContext.Provider value={ storeReference }>
         { children }
      </ReduxUpdateLessContext.Provider>
}

// Then use store in effects
const storeReference = useContext(ReduxUpdateLessContext);

storeReference.current.getState();
storeReference.current.dispatch(action);

useSelectState idea:

// Looks like we should create mapper function and memoize it,
// and pass new properties if they are changed as it was in connect function.
// Return the same object reference if nothing is changed
const { key1, key2 } = useSelectState((state, [dep1, dep2]) => ({
   key1: selectorA(state, dep1),
   key2: selectorB(state, dep2),
}), [propsDep1, propsDep2])

function useSelectState(mapper, propsArray) {
   const storeReference = useContext(ReduxUpdateLessContext);
   const mapperCallback = useCallback((state) => mapper(propsArray), propsArray);
   const [mappedState, setMappedState] = useState(mapperCallback(storeReference.current.getState()));

   useEffect(
        () => {
            const store = storeReference.current;
            let previousMappedState = mappedState;

            function onStoreChanged() {
                const nextMappedState = mapperCallback(store.getState());

                if(shallowEq(previousMappedState, nextMappedState)) {
                    setMappedState(nextMappedState);
                }
            }

            // get store somehow without context?
            const cleanupStoreSubscribe = store.subscribe(onStoreChanged);

            return cleanupStoreSubscribe;
        },
        [], // prevent calling twice
    );
}

useActionCreator(s) idea:

// Do we need to know about name `dispatch` function if we have only action creators
// It was good to know when we had special mapper outside `react-redux`
const { requestA } = useActionCreators({
   requestA: requestACreator,
})
// Do we need several `useActionCreator` hooks?
// Is it excessively?
const methodA = useActionCreator(actionCreatorA);
const methodB = useActionCreator(actionCreatorB);
const methodC = useActionCreator(actionCreatorC);

// Something like?
function useActionCreator(actionCreator) {
   const storeReference = useContext(ReduxUpdateLessContext);

   // get dispatch method from Store without making additional Consumer
   // somehow!?
   return useCallback((...args) => {
       storeReference.current.dispatch(actionCreator(...args));
   })
}
@timdorr
Copy link
Member

timdorr commented Feb 13, 2019

Please see #1177

@timdorr timdorr closed this as completed Feb 13, 2019
@markerikson
Copy link
Contributor

Also #1179 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants