Search code examples
reactjslodash

Refactor small function using lodash/fp map, and a second argument


I have a lodash/fp map function that returns a component, Lead. It is passed a list of leads (over which I iterate), but I also want to pass an id, that ill pass into each component (same id into each component)

I pass the array and the string into the component:

<tbody>{renderLeads(leads, advisor.id)}</tbody>

and my function returns a mapped array of leads:

const renderLeads = map(({ node: lead }) => { <--- how do i pass advisor.id into this function
   return <Lead lead={lead} advisorId={advisorId} key={lead.id} />;
});

How do I add the prop advisor.id (the second argument) into that map?


Solution

  • You can use currying to generate the map's callback with the advisorId:

    const renderLeads = pipe( // pipe is an alias of `_.flow()`
      advisorId => ({ node: lead }) => (
        <Lead lead={lead} advisorId={advisorId} key={lead.id} />
      ),
      map
    );
    

    To use it:

    <tbody>{renderLeads(advisor.id)(leads)}</tbody>
    

    Example:

    const { pipe, map } = _;
    
    const Lead = ({ lead, advisorId }) => (
      <div>{lead.txt} : {advisorId}</div>
    );
    
    const renderLeads = pipe(
      advisorId => ({ node: lead }) => (
        <Lead lead={lead} advisorId={advisorId} key={lead.id} />
      ),
      map
    );
    
    const Demo = ({ leads, advisor }) => (
      <div>{renderLeads(advisor.id)(leads)}</div>
    );
    
    const leads = [{ node: { id: 1, txt: 'lead-1' }}, { node: { id: 2, txt: 'lead-2' }}, { node: { id: 3, txt: 'lead-3' }}];
    
    ReactDOM.render(
      <Demo leads={leads} advisor={{ id: '154' }} />,
      root
    );
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    
    <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
    
    <div id="root"></div>