Home > Software design >  Avoid prop drilling in mapped components
Avoid prop drilling in mapped components

Time:10-22

Im mapping over some data and returning a NestedComponentOne each time. A nested child component NestedComponentThree needs access to a restaurant. How can I avoid prop drilling here? Wrapping every NestedComponentOne in a provider seems wrong.


const DATA = ["Restaurant 1"," Resto 2", "resto 3"]

export default DATA
import data from './data'


export default function App() {
  return (
    <div className="App">
      {data.map((restaurant) => {
        return <NestedComponentOne/>
      })}
    </div>
  );
}

const NestedComponentOne = () => <div><NestedComponentTwo/></div>
const NestedComponentTwo = () => <div><NestedComponentThree/></div>
// I need access to restaurant
const NestedComponentThree = () => <div>restaurant</div>

CodePudding user response:

The React doc recommends component composition:

Context is primarily used when some data needs to be accessible by many components at different nesting levels. Apply it sparingly because it makes component reuse more difficult.

If you only want to avoid passing some props through many levels, component composition is often a simpler solution than context.

So, you could for example do the following:

const data = ['Restaurant 1', ' Resto 2', 'resto 3'];
export default function App() {
    return (
        <div className="App">
            {data.map((restaurant) => {
                return (
                    <NestedComponentOne>
                        <NestedComponentTwo>
                            <NestedComponentThree restaurant={restaurant} />
                        </NestedComponentTwo>
                    </NestedComponentOne>
                );
            })}
        </div>
    );
}

const NestedComponentOne = ({ children }) => <div>{children}</div>;
const NestedComponentTwo = ({ children }) => <div>{children}</div>;
// Now you have access in this component to restaurant
const NestedComponentThree = ({ restaurant }) => <div>{restaurant}</div>;

Another way to do this is by passing the component as a prop:

const data = ['Restaurant 1', ' Resto 2', 'resto 3'];
export default function App() {
    return (
        <div className="App">
            {data.map((restaurant) => {
                return (
                    <NestedComponentOne
                        componentTwo={
                            <NestedComponentTwo
                                componentThree={
                                    <NestedComponentThree restaurant={restaurant} />
                                }
                            />
                        }
                    />
                );
            })}
        </div>
    );
}

const NestedComponentOne = ({ componentTwo }) => <div>{componentTwo}</div>;
const NestedComponentTwo = ({ componentThree }) => <div>{componentThree}</div>;
// Now you have access in this component to restaurant
const NestedComponentThree = ({ restaurant }) => <div>{restaurant}</div>;
  • Related