1

I'm taking an array and filtering the value in a context:

const { responsible } = useResponsible()
const [ids, setIds] = useState([])

const filteredResponsible = responsible?.filter((resp) =>
    ids.includes(resp.id)
  )

The problem is that I need to make a map to get the corresponding value of each id, one by one. This ends up making the code too long:

 const { filteredResponsible } =  useResponsible

 const responsibleName =  filteredResponsible.map((resp) => resp.name)

 const responsibleEmail =  filteredResponsible.map((resp) => resp.email)

 const responsibleAddress =  filteredResponsible.map((resp) => resp.address)
     ...

And so on with each item in the array.

I'm using the React Hook Form's setValue to set the value in the inputs:

useEffect(() => {
    setValue('name', `${responsibleName}`)
    setValue('email', `${responsibleEmail}`)
    setValue('address', `${responsibleAddress}`)
    setValue('cep', `${responsibleCep}`)
    setValue('district', `${responsibleDistrict}`)
    setValue('city', `${responsibleCity}`)
    setValue('state', `${responsibleState}`)
    setValue('phone', `${responsiblePhone}`)
    setValue('sex', `${responsibleSex}`)
  }, [])

How can I make these maps smaller? Without having to make a map to get each item in the array?

1
  • Is it intentional that you rely on the implicit join when doing (for instance) setValue('name', ${responsibleName})? (Since responsibleName is an array with potentially multiple elements.) Commented Dec 14, 2022 at 17:44

1 Answer 1

1

There doesn't seem to be any reason to do those map calls on every render and to do them anywhere other than where you need them, since you only show using the result in a mount-only effect. Just do them there:

const { filteredResponsible } = useResponsible; // Is there really no `()` needed here?

useEffect(() => {
    setValue("name", `${filteredResponsible.map(({name}) => name)}`);
    setValue("email", `${filteredResponsible.map(({email}) => email)}`);
    setValue("address", `${filteredResponsible.map(({address}) => address)}`);
    // ...
}, []);

If you really need those distinct arrays on every render, unless you can change your data structures to be more amenable to your output I don't see you have a lot of options. You can at least avoid multiple loops through filteredResponsible:

const { filteredResponsible } =  useResponsible; // ()?

const responsibleName = [];
const responsibleEmail = [];
const responsibleAddress = [];

for (const { name, email, address } of filteredResponsible) {
    responsibleName.push(name);
    responsibleEmail.push(email);
    responsibleAddress.push(address);
}

And if that's really the case, you may want to avoid doing it on every render:

const { filteredResponsible } = useResponsible; // ()?

const { responsibleName, responsibleEmail, responsibleAddress } = useMemo(() => {
    const responsibleName = [];
    const responsibleEmail = [];
    const responsibleAddress = [];
    for (const { name, email, address } of filteredResponsible) {
        responsibleName.push(name);
        responsibleEmail.push(email);
        responsibleAddress.push(address);
    }
    return { responsibleName, responsibleEmail, responsibleAddress };
}, [filteredResponsible]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.