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

getState for all action creators #180

Closed
itrelease opened this issue Jun 25, 2015 · 1 comment
Closed

getState for all action creators #180

itrelease opened this issue Jun 25, 2015 · 1 comment

Comments

@itrelease
Copy link
Contributor

So suppose we create dispatcher with promise middleware:

import { createDispatcher, composeStores, createRedux } from 'redux';
import { Provider } from 'redux/react';
import * as stores from './stores/index';
import { thunkMiddleware, promiseMiddleware } from './middlewares';

const dispatcher = createDispatcher(
  composeStores(stores),
  getState => [promiseMiddleware, thunkMiddleware(getState)]
);
const redux = createRedux(dispatcher);

and we have some action:

function fetchTodoItem(todoItemId) {
  return {
    types: [FETCH_TODO_ITEM, FETCH_TODO_ITEM_OK, FETCH_TODO_ITEM_FAIL],
    promise: apiFetchTodoItem(todoItemId),
    todoItemId
  }
}

but in this action I want to check local state on presence this todo item to eliminate request, like this:

function fetchTodoItem(todoItemId, getState) {
  const { todos } = getState();

  if (todos[todoItemId]) {
    return;
  }

  return {
    types: [FETCH_TODO_ITEM, FETCH_TODO_ITEM_OK, FETCH_TODO_ITEM_FAIL],
    promise: apiFetchTodoItem(todoItemId),
    todoItemId
  }
}

The problem that I have no access to getState function.

One of the solutions is to pass to bindActionCreators optional argument getState function:

export default function bindActionCreators(actionCreators, dispatch, getState) {
 return mapValues(actionCreators, actionCreator =>
   (...args) => dispatch(actionCreator(...args, getState))
 );
}

so all actions can get state if they need it.

@gaearon @acdlite

@itrelease
Copy link
Contributor Author

Or we can rewrite promise middleware like this:

export default function promiseMiddleware(getState) {
  return (next) => {
    const recurse = (action) => {
      if (typeof action === 'function') {
        return action(recurse, getState);
      }

      const { promise, types, ...rest } = action;

      if (!promise) {
        return next(action);
      }

      const [REQUEST, SUCCESS, FAILURE] = types;

      next({ ...rest, type: REQUEST });

      return promise.then(
        (result) => next({ ...rest, result, type: SUCCESS }),
        (error) => next({ ...rest, error, type: FAILURE })
      );
    };

    return recurse;
  };
}

and action will look something like this:

function fetchTodoItem(todoItemId) {
  return (dispatch, getState) => {
    const { todos } = getState();

    if (todos[todoItemId]) {
      return;
    }

    return dispatch({
      types: [FETCH_TODO_ITEM, FETCH_TODO_ITEM_OK, FETCH_TODO_ITEM_FAIL],
      promise: apiFetchTodoItem(todoItemId),
      todoItemId
    });
  };
}

This was referenced Sep 23, 2020
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

1 participant