I'm trying to understand selectors in react with ReSelect, it's ok for now but i think something wrong with my logic.
1 - After ajax request, i get a list of "categories", with id, name and selected
2 - I'm using this list to create tags, when i click one of them, it change this parameter "selected" (true/false).
3 - Every "categories" are into a "product" which i can select with a dropdown.
Ok until now everything is working perfectly. onChange from my dropdown, i update my "product" states like that :
{fetching: false, items: [], selected: {}}
import { createSelector } from 'reselect'; const getSelectedProduct = state => state.products.selected; const getCategories = state => state.categories; export const filterByProducts = () => { return createSelector( getSelectedProduct, getCategories, (mp, categories) => { if (mp && typeof mp === 'object') { const mpCategories = mp.categories.split(','); categories.items.map(item => { item.selected = mpCategories.indexOf(item.id) >= 0; return item; }); } return categories; } ) }
When i change my product, it will update every selected categories, that's what i want. But onClick to a tag, i update categories states too :
export const selectCategory = category => { return (dispatch, getState) => { const state = getState(); if (state.categories) { let categories = state.categories.items; categories.map(item => { if (item.id === category) { item.selected = !item.selected; } return item; }); dispatch(receiveCategories(categories)); } } }
The code is working, but because i changed states onClick, the selector will loop through every categories and make is matching again, but i would like to avoid that.
onChange product, selector will execute (good) onClick category, because of the new states made in my action.js, selector will run another time (not good).
I was thinking about to merge 2 selectors instead of making an action call, but i'm not sure about it...
If you have some advices, it would be great :)
Thank you !
Ok, so i found something simple.
I created a new var called "selection" into my 'categories' actions to handle my selections (onclick tags).
Instead of watching state.categories, i only watch state.categories.items, so my "filterByProduct" will not update every time.
Then i created a new selector called 'updateSelectedCategories', which is watching 'filterByProduct' and state.categories.selection.
So, when i change my product, 'filterByProduct' and 'updateSelectedCategories' will update. When i change a category, only 'updateSelectedCategories' will update, so i don't love my previous matching.
Here the code :
import { createSelector } from 'reselect'; const getSelectedProduct = state => state.products.selected; const getCategories = state => state.categories.items; const getSelection = state => state.categories.selection; const filterByProduct = createSelector( getSelectedProduct, getCategories, (mp, categories) => { if (mp && typeof mp === 'object') { const mpCategories = mp.categories.split(','); categories.map(item => { item.selected = mpCategories.indexOf(item.id) >= 0; return item; }); } return categories; } ); export const updateSelectedCategories = createSelector( filterByProduct, getSelection, (categories, selection) => { if (selection.length > 0 && typeof selection === 'object') { categories.map(item => { if (selection.indexOf(item) >= 0) { item.selected = true; } return item; }); } return categories; } );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.