bsky
bsky

Reputation: 20222

Calling a method after state change

I am trying Redux in a project. I have a list of countries, all of which have a price, and I want to select the countries with prices between minPrice and maxPrice values. I am doing that in this method:

  filterPrice: function(minPrice, maxPrice) {
    var newCountries = [];
    _.forEach(this.props.countries, function(country) {
        var price = country["price"];
        if(minPrice <= price && price <= maxPrice) {
            newCountries.push(country);
        }
    });
    this.setState({countries: newCountries});
  }

Now, I would like this method to be called somehow by the Redux architecture.

I have this reducer:

const initialState = {
  minPrice: 0,
  maxPrice: Constants.PRICE_RANGE
};


export default function PriceReducer(state = initialState, action) {
  switch (action.type) {

    case types.UPDATE_MAX:
      return {
        maxPrice: action.maxPrice
      }
    case types.UPDATE_MIN:
      return {
        minPrice: action.minPrice
      }

    default:
      return state;
  }
}

And these actions:

export const updateMax = (maxPrice) => {
  return {
    type: types.UPDATE_MAX,
    maxPrice: maxPrice
  };
}

export const updateMin = (minPrice) => {
  return {
    type: types.UPDATE_MIN,
    minPrice: minPrice
  };
}

I am creating a store like this:

const store = createStore(PriceReducer);

And I am calling it like this:

store.dispatch({type: types.UPDATE_MIN, minPrice: 10});

So how can I call filterPrice? Or if I can't call it, how do I change the state?

Upvotes: 3

Views: 3677

Answers (2)

Mike
Mike

Reputation: 364

Redux should be the source of state in the component. You should be able to filter the list and changes to minPrice and maxPrice should trigger your rerender.

filteredByPrice: function() {
   return this.props.countries.filter(function(country){
      return this.props.minPrice <= this.props.country.price && 
        this.props.country.price <= this.props.maxPrice
   }
}
... 
render: function(){
  return ....
      {this.filteredByPrice().map(function(country){
        return <div> {country.name} </div>
      })} 
  ....

Upvotes: 0

Nikolai Mavrenkov
Nikolai Mavrenkov

Reputation: 1923

If you would like to use redux in the common way, you need to keep all you state in redux, to make it a single source of truth. So, the first thing you should do is to put you country list in redux. Then, if you need some calculated properties, like, countries filtered by price, it's time to make selectors, using reselect library. Also, it's a good idea to read corresponding section of redux documentation.

In the end, you architecture will look like this:

  • redux keeps minPrice, maxPrice and countries
  • your container component use selectors to retrive data from state, calculate derived data and pass it to presentational components

Upvotes: 3

Related Questions