2
votes

Say I have a main component which uses 2 sub components and i want to pass a styling object prop to those sub components. Is there a way of passing those props without passing them directly to the main component since those props are not directly assosiated with the main component but rather the sub components.

<MainComponent subComponentStyling={} />

I reckon I'd be able to do this where I pass the sub components down as children:

<MainComponent>
 <SubComponent1 style={} />
 <SubComponent1  style={} />
</MainComponent>

On the other hand those two sub components are tightly connected to main component since I will always pass multiple props from the main component to the sub components, so I can't really do the above since the functionality that I want to pass down exists in the main component.

Do I have to create a render prop and pass stuff down through that or is it more convient to pass the styling props down to main component and from main component to the sub component?

I'm newbie at react so I probably missed something basic.

3

3 Answers

4
votes

There are 3 ways of passing down props to subComponents:

Via normal props: Pass the props to the MainComponent which will pass it down to the SubComponent.

Caveat: In this case you will be interfering with the namespace of MainComponent and making MainComponent aware of the props accepted by its children which defeats abstraction.

Via render props: MainComponent will accept a render prop and will not be aware of what it is rendering.

Caveat: The SubComponent will be rendered by the parent which has the styles and passed down via render prop to be rendered inside the MainComponent. Here MainComponent is unaware of the props accepted by SubComponent and can pass it props that it wants. But the parent which has the styles is aware of the SubComponent. Plus in the future if any other component uses MainComponent in the future, it will have to keep passing SubComponent as render prop. So this defeats the DRY principle( Do not repeat yourself) .

Via context: Here you don’t need to pass anything to MainComponent. The component which has the styles will be the Provider and the SubComponent will be the consumer. Context API is part of React 16.

Caveat: Here the component which has the styles is only aware of the styles it needs to pass and SubComponent is only aware of the styles it needs to consume. MainComponent is blissfully unaware of this contract.

I recommend passing styles via Context to fulfill the purpose of keeping your code DRY and avoiding making MainComponent aware of the props passed down from top to SubCompoment.

1
votes

You can use Context provided by React to pass style to SubComponent without passing through MainComponent

Here's example for the same -

// Context lets us pass a value deep into the component tree
// without explicitly threading it through every component.
// Create a context for the current style (with "{display:none}" as the default).
const SubComponentStyleContext = React.createContext({display:none});

class App extends React.Component {
  render() {
    // Use a Provider to pass the current style to the tree below.
    // Any component can read it, no matter how deep it is.
    // In this example, we're passing "{display:block}" as the current value.
    return (
      <SubComponentStyleContext.Provider value={{display:block}}>
        <MainComponent />
      </SubComponentStyleContext.Provider>
    );
  }
}

// A component in the middle doesn't have to
// pass the style down explicitly anymore.
function MainComponent(props) {
  return (
    <div>
      <SubComponent />
    </div>
  );
}

function SubComponent(props) {
  // Use a Consumer to read the current style context.
  // React will find the closest theme Provider above and use its value.
  // In this example, the current style is "{display:block}".
  return (
    <SubComponentStyleContext.Consumer>
      {style => /*use style here as you want*/}
    </SubComponentStyleContext.Consumer>
  );
}
0
votes

I might be completely misunderstanding what you're asking(sorry if so). But if you want to pass styles down you can do it in an array like so.

<View style={[subComponentStyling, {backgroundColor: blue}]}>
  ...
</View>