Reputation: 69
In an earlier question I struggled with normalizing data with normalizr for storing into my Redux store.
This is the outcome: https://stackoverflow.com/a/70519781/16303828
const assistant = new schema.Entity("assistants");
const dentist = new schema.Entity("dentists");
const client = new schema.Entity("clients");
const userSchema = {
assistants: [assistant],
dentists: [dentist],
clients: [client]
};
const normalizedUsers = normalize(users, userSchema);
the outcome of a console.log(normalisedUsers) is now:
{entities: {…}, result: {…}}
entities:
assistants: {201: {…}, 202: {…}}
clients: {1: {…}, 2: {…}}
dentists: {101: {…}, 102: {…}}
[[Prototype]]: Object
result:
assistants: (2) [201, 202]
clients: (2) [1, 2]
dentists: (2) [101, 102]
[[Prototype]]: Object
[[Prototype]]: Object
Now the question is: how do I refactor the Components in React to get that data displayed. Or am I still in error on how I normalized my data, and should I alter something there?
Upvotes: 0
Views: 360
Reputation: 1301
You haven't actually shared any React components, so I'm just going to guess what you're trying to do. You want a <Assistant />
component to display each assistant, right? And same thing for clients and dentists.
Here's how I would do it, assuming the normalised data is in the redux store by now (note, requires lodash):
import { useSelector, shallowEqual } from 'react-redux'
import { keys, isEmpty } from 'lodash'
// ^ equivalent to Object.keys() but with safety checks
export function AssistantsList() {
const assistants = useSelector((state: RootState) => keys(state.assistants), shallowEqual)
if (isEmpty(assistants)) return null
return (
<div>
{assistants.map(id => (
<Assistant key={id} id={Number(id)} />
))}
</div>
)
}
// typescript stuff: ignore if not using typescript
interface AssistantProps {
id: number;
}
function Assistant({ id }: AssistantProps) {
const { first_name, last_name, phone, email } = useSelector(
(state: RootState) => state.assistants[id],
shallowEqual
)
return (
<div>
<b>Assistant #{id}</b>
<div>
{first_name} {last_name}
</div>
<a href={`tel:${phone}`}>{phone}</a>
<a href={`mailto:${email}`}>{email}</a>
</div>
)
}
// typescript stuff
type AssistantState = {
id: number;
first_name: string;
last_name: string;
phone: string;
email: string;
}
// in a real app would be ReturnType<typeof store.getState>
// (where `store` is the redux store)
type RootState = {
assistants: {
[id: number]: AssistantState
}
}
Upvotes: 1