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

Redux: When to Render Loading Icon #14

Open
Joldnine opened this issue Mar 2, 2018 · 0 comments
Open

Redux: When to Render Loading Icon #14

Joldnine opened this issue Mar 2, 2018 · 0 comments

Comments

@Joldnine
Copy link
Owner

Joldnine commented Mar 2, 2018

There is always a scenario that when data is being fetched from the server, the browser needs to display a spin icon. With react + redux, you may probably implement it in such way:

class SampleComponent extends React.Component {
  componentDidMount() {
    // dispatch the action here to fetch new data from the server and update the store
  }
  render() {
    if (// data is empty) { // or use conditional rendering
      return(<renderSpin />);
    }
    return (<renderWithData />);
  }
}

The implementation looks good at the first glance. However, the data may be incorrect in a case:

  1. SampleComponent mounts for the first time and the store is updated, where everything is fine.
  2. SampleComponent umounts.
  3. SampleComponent mounts for the second time and the fetching data is failed or takes a long time. The spin will be skipped because the data is not empty, but it is the data fetched from the first mount and is old.

We can see an unexpected behavior.

To avoid such problem, there could be 2 solutions.

  1. destroy the data in componentWillUnmount:
class SampleComponent extends React.Component {
  componentDidMount() {
    // dispatch the action here to fetch new data from the server and update the store
  }
  componentWillUnmount() {
    // dispatch the action here to make the data in the store empty
  }
  render() {
    if (// data is empty) {
      return(<renderSpin />);
    }
    return (<renderWithData />);
  }
}

This method is only applicable in the case that this data is not used in other components or you are confident that destroying the data upon umounting of this component is ok.
But if the data is not used in other components, why not use state instead of redux for this data?

  1. dispatch an empty data before fetching from the server in the action:
export const sampleData = () => {
  const url = `${ServerConst.SERVER_CONTEXT_PATH}/api/v1/xxx`;
  return (dispatch) => {
    dispatch({ // dispatch a default value
      type: ActionTypes.SAMPLE_DATA,
      data: [] // or null,
    });
    return fetchApi(url)
    .then(response => response.json())
    .then(data => dispatch({
      type: ActionTypes.SAMPLE_DATA,
      data,
    }));
  };
};

This method is applicable for most cases, but it will dispatch twice in each data updating.

Comment on this issue if you have other ideas.

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