简体   繁体   中英

react selectors, handle onload state and onclick together

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: {}}
  • with the help of a selector, when the selected product change, i filter my categories to match my selection :

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM