How to create one instance for an instance in Redux?

Sometimes it would be useful to create one instance for each instance in Redux applications. The creator of Redux himself created a Gist that describes how to do this: https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400

I asked this question already in Gist, but I think StackOverflow will be the best place for this question:

I wonder how to do dispatchactions for your own special repository of components? Is there a way to access store-prop <Provider />for each <SubApp />(and their child components)?

For example: I have some API classes that call dispatchafter retrieving data from a remote server. But since I can't import a β€œnormal” store, what would be the best way to handle custom stores to make them available to other classes / files / services?

Update 1

So, I got it working, but I think this is a really dirty way (remember the comments UGLY?inside the code):

Provider:

Create a repository for each instance by creating a repository inside the constructor:

export default class OffersGridProvider extends React.Component {
  constructor(props) {
    super(props)
    this.store = createStore(reducers);
  }

  render() {
    return (
      <Provider store={this.store}>
        <OffersGridContainer offers={this.props.offers} />
      </Provider>
    );
  }
}

Container:

The provider implements the method dispatchfor this repository to mine OffersGridContainer, which I can use to send actions only to the repository of this instance:

class OffersGridContainer extends React.Component {    
  componentDidMount() {

    // UGLY???
    const { dispatch } = this.props;

    let destinationIds = [];
    this.props.offers.forEach((offer) => {
      offer.to.forEach((destination) => {
        destinationIds.push(destination.destination);
      });
    });

    // MORE UGLY???
    destinationsApi.getDestinations(dispatch, destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

export default connect(mapStateToProps)(OffersGridContainer);

API Method:

dispatch, API:

export function getDestinations(dispatch, ids) {
  const url = $('meta[name="site-url"]').attr('content');

  const filter = ids.map((id) => {
    return `filter[post__in][]=${id}`;
  }).join('&');

  return axios.get(`${url}/wp-json/wp/v2/destinations?filter[posts_per_page]=-1&${filter}`)
    .then(response => {
      dispatch(getOffersGridSuccess(response.data));
      return response;
    });
}

2

mapDispatchToProps , Container :

class OffersGridContainer extends React.Component {    
  componentDidMount() {
    let destinationIds = [];

    this.props.offers.forEach((offer) => {
      offer.to.forEach((destination) => {
        destinationIds.push(destination.destination);
      });
    });

    this.props.getDestinations(destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

const mapDispatchToProps = function(dispatch) {
  return {
    getDestinations: function(ids) {
      return destinationsApi.getDestinations(dispatch, ids);
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(OffersGridContainer);

3 ( )

! :

Provider:

export default class OffersGridProvider extends React.Component {    
  constructor(props) {
    super(props)
    this.store = createStore(reducers, applyMiddleware(thunk));
  }

  render() {
    return (
      <Provider store={this.store}>
        <OffersGridContainer offers={this.props.offers} />
      </Provider>
    );
  }
}

:

class OffersGridContainer extends React.Component {
  componentDidMount() {
    const destinationIds = this.props.offers.reduce((acc, offer) => {
      return [...acc, ...offer.to.map(d => d.destination)];
    }, []);

    this.props.getDestinations(destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

const mapDispatchToProps = function(dispatch) {
  return {
    getDestinations: function(ids) {
      return dispatch(destinationsApi.getDestinations(ids));
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(OffersGridContainer);

API-:

export function getDestinations(ids) {
  return function(dispatch) {
    const url = $('meta[name="site-url"]').attr('content');

    const filter = ids.map((id) => {
      return `filter[post__in][]=${id}`;
    }).join('&');

    return axios.get(`${url}/wp-json/wp/v2/destinations?filter[posts_per_page]=-1&${filter}`)
      .then(response => {
        return dispatch(getOffersGridSuccess(response.data));
      });
  }
}
+4
1

api redux-thunk.

mapDispatchToProps connect, :

import { getDestinations } from '../actions';

class OffersGridContainer extends React.Component {    
  componentDidMount() {
    // Tip.
    const destinationIds = this.props.offers.reduce((acc, offer) => {
      return [...acc, ...offer.to.map(d => d.destination)];
    }, []);

    // instead `destinationsApi.getDestinations(dispatch, destinationIds)`
    // call action creator function
    this.props.getDestinations(destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

const mapDispatchToProps = function(dispatch) {
  return {
    // this function will be available in component as   
    // `this.props.getDestinations`.
    getDestinations: function(destinationIds) {
      dispatch(getDestinations(destinationIds));
    }
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(OffersGridContainer);
+1

Source: https://habr.com/ru/post/1650501/


All Articles