EzDev.org

redux

redux - Predictable state container for JavaScript apps Read Me · Redux


How to dispatch a Redux action with a timeout?

I have an action that updates notification state of my application. Usually this notification will be an error or info of some sort. I need to then dispatch another action after 5 seconds that will return the notification state to initially one, so no notification. Main reason behind this is to provide functionality where notifications disappear automatically after 5 seconds.

I had no luck with using setTimeout and returning another action and can't find how this is done online. So any advice is welcome.


Source: (StackOverflow)

Why use Redux over Facebook Flux?

I've read this answer, reducing boilerplate, looked at few GitHub examples and even tried redux a little bit (todo apps).

As I understand, official redux doc motivations provide pros comparing to traditional MVC architectures. BUT it doesn't provide an answer to the question:

Why you should use Redux over Facebook Flux?

Is that only a question of programming styles: functional vs non-functional? Or the question is in abilities/dev-tools that follow from redux approach? Maybe scaling? Or testing?

Am I right if I say that redux is a flux for people who comes from functional languages?

To answer this question you may compare complexity of implementation redux's motivation points on flux vs redux.

Here are motivation points from official redux doc motivations:

  1. Handling optimistic updates (as I understand, it hardly depends on 5th point. Is it hard to implement it in fb flux?)
  2. Rendering on the server (fb flux also can do this. Any benefits comparing to redux?)
  3. Fetching data before performing route transitions (Why it can't be achieved in fb flux? What's the benefits?)
  4. Hot reload (It's possible with React Hot Reload. Why do we need redux?)
  5. Undo/Redo functionality
  6. Any other points? Like persisting state...

Source: (StackOverflow)

Why do we need middleware for async flow in Redux?

According to the docs, "Without middleware, Redux store only supports synchronous data flow". I don't understand why this is the case. Why can't the container component call the async API, and then dispatch the actions?

For example, imagine a simple UI: a field and a button. When user pushes the button, the field gets populated with data from a remote server.

A field and a button

import * as React from 'react';
import * as Redux from 'redux';
import { Provider, connect } from 'react-redux';

const ActionTypes = {
    STARTED_UPDATING: 'STARTED_UPDATING',
    UPDATED: 'UPDATED'
};

class AsyncApi {
    static getFieldValue() {
        const promise = new Promise((resolve) => {
            setTimeout(() => {
                resolve(Math.floor(Math.random() * 100));
            }, 1000);
        });
        return promise;
    }
}

class App extends React.Component {
    render() {
        return (
            <div>
                <input value={this.props.field}/>
                <button disabled={this.props.isWaiting} onClick={this.props.update}>Fetch</button>
                {this.props.isWaiting && <div>Waiting...</div>}
            </div>
        );
    }
}
App.propTypes = {
    dispatch: React.PropTypes.func,
    field: React.PropTypes.any,
    isWaiting: React.PropTypes.bool
};

const reducer = (state = { field: 'No data', isWaiting: false }, action) => {
    switch (action.type) {
        case ActionTypes.STARTED_UPDATING:
            return { ...state, isWaiting: true };
        case ActionTypes.UPDATED:
            return { ...state, isWaiting: false, field: action.payload };
        default:
            return state;
    }
};
const store = Redux.createStore(reducer);
const ConnectedApp = connect(
    (state) => {
        return { ...state };
    },
    (dispatch) => {
        return {
            update: () => {
                dispatch({
                    type: ActionTypes.STARTED_UPDATING
                });
                AsyncApi.getFieldValue()
                    .then(result => dispatch({
                        type: ActionTypes.UPDATED,
                        payload: result
                    }));
            }
        };
    })(App);
export default class extends React.Component {
    render() {
        return <Provider store={store}><ConnectedApp/></Provider>;
    }
}

When the exported component is rendered, I can click the button and the input is updated correctly.

Note the update function in the connect call. It dispatches an action that tells the App that it is updating, and then performs an async call. After the call finishes, the provided value is dispatched as a payload of another action.

What is wrong with this approach? Why would I want to use Redux Thunk or Redux Promise, as the documentation suggests?

EDIT: I searched the Redux repo for clues, and found that Action Creators were required to be pure functions in the past. For example, here's a user trying to provide a better explanation for async data flow:

The action creator itself is still a pure function, but the thunk function it returns doesn't need to be, and it can do our async calls

Action creators are no longer required to be pure. So, thunk/promise middleware was definitely required in the past, but it seems that this is no longer the case?


Source: (StackOverflow)

Pros/cons of using redux-saga with ES6 generators vs redux-thunk with ES7 async/await

There is a lot of talk about the latest kid in redux town right now, yelouafi/redux-saga. It uses generator functions for listening to/dispatching actions.

Before I wrap my head around it, I would like to know the pros/cons of using redux-saga instead of the approach below where I'm using redux-thunk with async/await.

A component might look like this, dispatch actions like usual.

import { login } from 'redux/auth';

class LoginForm extends Component {

  onClick(e) {
    e.preventDefault();
    const { user, pass } = this.refs;
    this.props.dispatch(login(user.value, pass.value));
  }

  render() {
    return (<div>
        <input type="text" ref="user" />
        <input type="password" ref="pass" />
        <button onClick={::this.onClick}>Sign In</button>
    </div>);
  } 
}

export default connect((state) => ({}))(LoginForm);

Then my actions look something like this:

// auth.js

import request from 'axios';
import { loadUserData } from './user';

// define constants
// define initial state
// export default reducer

export const login = (user, pass) => async (dispatch) => {
    try {
        dispatch({ type: LOGIN_REQUEST });
        let { data } = await request.post('/login', { user, pass });
        await dispatch(loadUserData(data.uid));
        dispatch({ type: LOGIN_SUCCESS, data });
    } catch(error) {
        dispatch({ type: LOGIN_ERROR, error });
    }
}

// more actions...

// user.js

import request from 'axios';

// define constants
// define initial state
// export default reducer

export const loadUserData = (uid) => async (dispatch) => {
    try {
        dispatch({ type: USERDATA_REQUEST });
        let { data } = await request.get(`/users/${uid}`);
        dispatch({ type: USERDATA_SUCCESS, data });
    } catch(error) {
        dispatch({ type: USERDATA_ERROR, error });
    }
}

// more actions...

Source: (StackOverflow)

What could be the downsides of using Redux instead of Flux

I just recently discovered Redux. It all looks good. Is there any downsides, gotcha or compromises from using Redux instead of Flux? Thanks


Source: (StackOverflow)

What's the '@' (at symbol) in the Redux @connect decorator?

I am learning Redux with React and stumbled upon this code. I am not sure if it is Redux specific or not, but I have seen the following code snippet in one of the examples.

@connect((state) => {
  return {
    key: state.a.b
  };
})

While the functionality of connect is pretty straightforward, but I don't understand the @ before connect. It isn't even a JavaScript operator if I am not wrong.

Can someone explain please what is this and why is it used?

Update:

It is in fact a part of react-redux which is used to connects a React component to a Redux store.


Source: (StackOverflow)

React + Redux - What's the best way to handle CRUD in a form component?

I got one form who is used to Create, Read, Update and Delete. I created 3 components with the same form but I pass them differents props. I got CreateForm.js, ViewForm.js (readonly with the delete button) and UpdateForm.js.

I used to work with PHP, so I always did these in one form.

I use React and Redux to manage the store.

When I'm in the CreateForm component, I pass to my sub-components this props createForm={true} to not fill the inputs with a value and don't disable them. In my ViewForm component, I pass this props readonly="readonly".

And I got another problem with a textarea who is filled with a value and is not updatable. React textarea with value is readonly but need to be updated

What's the best structure to have only one component who handle these differents states of the form?

Do you have any advices, tutorials, videos, demos to share?


Source: (StackOverflow)

Redux - multiple stores, why not?

As a note: I've read the docs for Redux (Baobab, too), and I've done a fair share of Googling & testing.

Why is it so strongly suggested that a Redux app have only one store?

I understand the pros/cons of a single-store setup vs a multiple store setup (There are many Q&A on SO on this subject).

IMO, this architectural decision belongs to the app developers based on their projects' needs. So why is it so strongly suggested for Redux, almost to the point of sounding mandatory (though nothing is stopping us from making multiple stores)?

EDIT: feedback after converting to single-store

After a few months working with redux on what many would consider a complex SPA, I can say that the single store structure has been a pure delight to work with.

A few points that might help others understand why single store vs many store is a moot question in many, many use-cases:

  • it's reliable: we use selectors to dig through the app state and obtain context-relevant information. We know that all the needed data is in a single store. It avoids all questioning as to where state issues could be.
  • it's fast: our store currently has close to 100 reducers, if not more. Even at that count, only a handful of reducers process data on any given dispatch, the others just return the previous state. The argument that a huge/complex store (nbr of reducers) is slow is pretty much moot. At least we've not seen any performance issues coming from there.
  • debugging friendly: while this is a most convincing argument to use redux as a whole, it also goes for single store vs multiple store. When building an app you're bound to have state errors in the process (programmer mistakes), it's normal. The PITA is when those errors take hours to debug. Thanks to the single store (and redux-logger) we've never spent more than a few minutes on any given state issue.

a few pointers

The true challenge in building your redux store is when deciding how to structure it. Firstly, because changing structure down the road is just a major pain. Secondly, because it largely determines how you'll be using, and querying your app data for any process. There are many suggestions on how to structure a store. In our case we found the following to be ideal:

{
  apis: {     // data from various services
    api1: {},
    api2: {},
    ...
  }, 
  components: {} // UI state data for each widget, component, you name it 
  session: {} // session-specific information
}

Hopefully this feedback will help others.

EDIT 2 - helpful store tools

For those of you who have been wondering how to "easily" manage a single store, which can quickly get complex. There are a tools that help isolate the structural dependencies/logic of your store.

There is Normalizr which normalizes your data based on a schema. It then provides an interface to work with your data and fetch other parts of your data by id, much like a Dictionary.

Not knowing Normalizr at the time, I built something along the same lines. relational-json takes a schema, and returns a Table-based interface (a little like a database). The advantage of relational-json is that your data structure dynamically references other parts of your data (essentially, you can traverse your data in any direction, just like normal JS objects). It's not as mature as Normalizr, but I've been using it successfully in production for a few months now.


Source: (StackOverflow)

How can I display a modal dialog in Redux that performs asynchronous actions?

I'm building an app that needs to show a confirm dialog in some situations.

Let's say I want to remove something, then I'll dispatch an action like deleteSomething(id) so some reducer will catch that event and will fill the dialog reducer in order to show it.

My doubt comes when this dialog submits.

  • How can this component dispatch the proper action according to the first action dispatched?
  • Should the action creator handle this logic?
  • Can we add actions inside the reducer?

edit:

to make it clearer:

deleteThingA(id) => show dialog with Questions => deleteThingARemotely(id)

createThingB(id) => Show dialog with Questions => createThingBRemotely(id)

So I'm trying to reuse the dialog component. Showing/hiding the dialog it's not the problem as this can be easily done in the reducer. What I'm trying to specify is how to dispatch the action from the right side according to the action that starts the flow in the left side.


Source: (StackOverflow)

How to dynamically load reducers for code splitting in a Redux application?

I'm going migrate to Redux.

My application consists of a lot of parts (pages, components) so I want to create many reducers. Redux examples show that I should use combineReducers() to generate one reducer.

Also as I understand Redux application should have one store and it is created once the application starts. When the store is being created I should pass my combined reducer. This makes sense if the application is not too big.

But what if I build more than one JavaScript bundle? For example, each page of application has own bundle. I think in this case the one combined reducer is not good. I looked through the sources of Redux and I have found replaceReducer() function. It seems to be what I want.

I could create combined reducer for each part my application and use replaceReducer() when I move between parts of application.

Is this a good approach?


Source: (StackOverflow)

React / Redux and Multilingual (Internationalization) Apps - Architecture

I'm building an app that will need to be available in multiple languages and locales.

My question is not purely technical, but rather about the architecture, and the patterns that people are actually using in production to solve this problem. I couldn't find anywhere any "cookbook" for that, so I'm turning to my favourite Q/A website :)

Here are my requirements (they are really "standard"):

  • The user can choose the language (trivial)
  • Upon changing the language, the interface should translate automatically to the new selected language
  • I'm not too worried about formatting numbers, dates etc. at the moment, I want a simple solution to just translate strings

Here are the possible solutions I could think off:

Each component deal with translation in isolation

This means that each component have for example a set of en.json, fr.json etc. files alongside it with the translated strings. And a helper function to help reading the values from those depending on the selected language.

  • Pro: more respectful of the React philosophy, each component is "standalone"
  • Cons: you can't centralize all the translations in a file (to have someone else add a new language for example)
  • Cons: you still need to pass the current language as a prop, in every bloody component and their children

Each component receives the translations via the props

So they are not aware of the current language, they just take a list of strings as props which happen to match the current language

  • Pro: since those strings are coming "from the top", they can be centralized somewhere
  • Cons: Each component is now tied into the translation system, you can't just re-use one, you need to specify the correct strings every time

You bypass the props a bit and possibly use the context thingy to pass down the current language

  • Pro: it's mostly transparent, don't have to pass the current language and/or translations via props all the time
  • Cons: it looks cumbersome to use

If you have any other idea, please do say!

How do you do it?


Source: (StackOverflow)

How to reset the state of a Redux store?

I am using Redux for state management.
How do I reset the store to its initial state?

For example, let’s say I have two user accounts (u1 and u2).
Imagine the following sequence of events:

  1. User u1 logs into the app and does something, so we cache some data in the store.

  2. User u1 logs out.

  3. User u2 logs into the app without refreshing the browser.

At this point, the cached data will be associated with u1, and I would like to clean it up.

How can I reset the Redux store to its initial state when the first user logs out?


Source: (StackOverflow)

Accessing Redux state in an action creator?

Say I have the following:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
  }
}

And in that action creator, I want to access the global store state (all reducers). Is it better to do this:

import store from '../store';

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
    items: store.getState().otherReducer.items,
  }
}

or this:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return (dispatch, getState) => {
    const {items} = getState().otherReducer;

    dispatch(anotherAction(items));
  }
}

Source: (StackOverflow)

How to sync Redux state and url hash tag params

We have a list of lectures and chapters where the user can select and deselect them. The two lists are stored in a redux store. Now we want to keep a representation of selected lecture slugs and chapter slugs in the hash tag of the url and any changes to the url should change the store too (two-way-syncing).

What would be the best solution using react-router or even react-router-redux?

We couldn't really find some good examples where the react router is only used to maintain the hash tag of an url and also only updates one component.

Thanks!!!


Source: (StackOverflow)

Firing Redux actions in response to route transitions in React Router

I am using react-router and redux in my latest app and I'm facing a couple of issues relating to state changes required based on the current url params and queries.

Basically I have a component that needs to update it's state every time the url changes. State is being passed in through props by redux with the decorator like so

 @connect(state => ({
   campaigngroups: state.jobresults.campaigngroups,
   error: state.jobresults.error,
   loading: state.jobresults.loading
 }))

At the moment I am using the componentWillReceiveProps lifecycle method to respond to the url changes coming from react-router since react-router will pass new props to the handler when the url changes in this.props.params and this.props.query - the main issue with this approach is that I am firing an action in this method to update the state - which then goes and passes new props the component which will trigger the same lifecycle method again - so basically creating an endless loop, currently I am setting a state variable to stop this from happening.

  componentWillReceiveProps(nextProps) {
    if (this.state.shouldupdate) {
      let { slug } = nextProps.params;
      let { citizenships, discipline, workright, location } = nextProps.query;
      const params = { slug, discipline, workright, location };
      let filters = this._getFilters(params);
      // set the state accroding to the filters in the url
      this._setState(params);
      // trigger the action to refill the stores
      this.actions.loadCampaignGroups(filters);
    }
  }

Is there a standard approach to trigger actions base on route transitions OR can I have the state of the store directly connected to the state of the component instead of passing it in through props? I have tried to use willTransitionTo static method but I don't have access to the this.props.dispatch there.


Source: (StackOverflow)