1

For your information, I have following code:

const companyPagesAdapter = createEntityAdapter<CompanyPage>(
        {
            selectId: model => model.pageNumber,
            sortComparer: (a, b) => a.pageNumber>b.pageNumber? 1 : a.pageNumber<b.pageNumber? -1 : 0
        }
    );

type CompanyPage = {
    companyIds: number[],
    pageNumber: number,
    isDirty: boolean
}

So my state in companyPagesSlice slice looks like this:

{
  ids: number[],
  entities: {
    [key: number]: CompanyPage;
  }
}

Then in my component I extract company ids for a page like this:

const companyIds = useSelector(state => state.companyPages.entities[pageNumber].companyIds);

My companySlice slice state looks like this:

{
  ids: number[],
  entities: {
    [key: number]: ICompany;
  }
}

where ICompany is:

type ICompany = {
    id: number;
    name: string;
    status: Status;
    country: string;
    city: string;
    address: string;
    zipCode: number;
}

Is there any possible way to select multiple entities from redux store with useSelector hook by passing an array of ids or anything else?

I tried to solve it this way:

const companies = companyIds?.map(item => {
        const company = useSelector(state => selectCompanyById(state.companies, item));
        if (!company)
            return;
        return company;
    })

But it unfortunately breaks rule of react hooks: you can't evoke hook inside a loop.

Dima Kambalin
  • 283
  • 2
  • 12

2 Answers2

4

Here is how you can do it another way:

const companies = useSelector(state => {
        return companyIds?.map(item => {
            if (state.companies.entities[item])
                return state.companies.entities[item];
            return;
        });
    });
Dima Kambalin
  • 283
  • 2
  • 12
0

Depending on your precise needs, you could select all the companies (allCompanies) and then just pull out the ones you want:

const companyIds = useSelector(state => state.companyPages.entities[pageNumber].companyIds);
const allCompanies = useSelector(state => state.company);

const companies = Object.values(allCompanies).filter(({ids}) => companyIds.some(id => ids.includes(id)))

You can do it more performantly with refs and effects, but it gets more complicated. Because react is fast out of the box, I'd start with what I've shown you above.

Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100