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

Docs: Example of component that asks for data asynchonously #202

Closed
bapti opened this issue Jul 1, 2015 · 3 comments
Closed

Docs: Example of component that asks for data asynchonously #202

bapti opened this issue Jul 1, 2015 · 3 comments

Comments

@bapti
Copy link

bapti commented Jul 1, 2015

Hi, I'm coming to react new in the last week or so and I implemented a basic app with Redux. In your docs you've got a section https://github.com/gaearon/redux#how-do-stores-actions-and-components-interact which I think describes what I'm trying to achieve.

Say we have your counter component from an earlier example and there was an action called fetchCountAsync how would that tie in to the below example? Sorry if I'm being dumb!

@connect(state => ({
  counter: state.counter
}))
export default class CounterApp {
  render() {
    const { counter, dispatch } = this.props;
    const actionCreators = bindActionCreators(CounterActions, dispatch)
    return (
      <Counter counter={counter} {...actionCreators} />
    );
  }
}

Where should this be call for data be invoked? Is adding a constructor a good idea if that's possible with the scoping or should it be in the render function itself?

Thanks for any help!

@clearjs
Copy link
Contributor

clearjs commented Jul 1, 2015

If you need some data to be loaded asynchronously, there should be an action creator for that. It just performs an async request, and upon receiving a response creates an action with results, and passes that to the dispatcher function.

Then some reducer gets that action, and returns a new state which includes the information from action. Lets say it is stored as state.counter.

state.counter will be passed as the counter prop to the CounterApp component. See
https://github.com/gaearon/redux/blob/master/src/components/createConnector.js#L83, where ...slice is used to pass all props specified in the decorator. From CounterApp to Counter it can be passed via a prop, but wasn't in your example.

As for the action creator itself, it is available via a prop to the Counter component. In your example, {...actionCreators} is used to pass it.

@pburtchaell
Copy link

You can return a promise in your action creator and then handle the promise with Redux middleware.

For example:

// actions.js
export function myAsyncActionCreator() {
  return {
    types: [
      'ACTION_PENDING',
      'ACTION_FULFILLED',
      'ACTION_REJECTED'
    ],
    payload: doSomethingAyncAndReturnPromise()
  };
}

// reducer.js
export default function myReducer(state = {}, action) {
  switch (action.type) {
    case 'ACTION_PENDING':
      return {
        ...state,
        isPending: true,
      };
    case 'ACTION_FULFILLED':
      return {
        ...state,
        isPending: false,
        isFulfilled: true
      };
  }
}

Within your component you can do things like show a spinner when this.props.isPending is true.

I have some middleware to help out here: https://github.com/pburtchaell/redux-promise-middleware. Under the hood, it dispatches two actions: one for pending, a second for rejected or fulfilled.

@gaearon
Copy link
Contributor

gaearon commented Jul 20, 2015

We will definitely have this in new docs.
Some meaningful discussion has also been happening in #291 and #99.

I'll close this.

@gaearon gaearon closed this as completed Jul 20, 2015
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

4 participants