question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[RFC] What's the best API to override deep/nested elements?

See original GitHub issue

A while back, around the alpha & beta iterations on the v1 version, we had to decide what was the best way to override the nested components. It’s meant to help developers customize the rendering. We can find #11204 and #10476 as a legacy.

up until v1

So far, the tradeoff on this problem has been:

  1. Provide a XXXComponent prop when overriding the nested element can be valuable for users. For instance:

https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui/src/Modal/Modal.d.ts#L8

  1. Provide a XXXProps prop when providing a custom XXXComponent component is too cumbersome. For instance:

https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui/src/Modal/Modal.d.ts#L9

However, this original design constraint is increasingly more challenged by the following:

Autocomplete

The Autocomplete mixes the renderXXX approach with the XXXComponent approach. cc @oliviertassinari

https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts#L164 https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts#L142

Date Picker

The DatePicker mixes the renderXXX approach with the XXXComponent approach. cc @dmtrKovalenko

renderLoading?: () => React.ReactNode;

https://github.com/mui-org/material-ui-pickers/blob/c834f5cac5930df099aaad806ceb3fe4ec1669db/lib/src/views/Calendar/Calendar.tsx#L43

ToolbarComponent?: React.ComponentType<ToolbarComponentProps>;

https://github.com/mui-org/material-ui-pickers/blob/c834f5cac5930df099aaad806ceb3fe4ec1669db/lib/src/typings/BasePicker.tsx#L61

Data Drid

The DataGrid goes with xXXComponent approach, however, the name is confusing. Sometimes it’s a render prop, sometimes it’s a React element, it’s never a component as the name suggests cc @dtassone

  paginationComponent?: (props: PaginationProps) => React.ReactNode;
  loadingOverlayComponent?: React.ReactNode;
  noRowsOverlayComponent?: React.ReactNode;
  footerComponent?: (params: ComponentParams) => React.ReactNode;
  headerComponent?: (params: ComponentParams) => React.ReactNode;

https://github.com/mui-org/material-ui-x/blob/59d533642d5837ce6912fe88cbcdfc228f621594/packages/grid/x-grid-modules/src/models/gridOptions.tsx#L93-L97

Styled components

Styled components might request something brand new. cc @mnajdova As the experimentation of #21104 showcases. If we want to keep the CSS specificity at it’s lowest possible level (meaning one level) and expose unstyled components, we will have to expose an API to inject custom component. In older experimentation, I worked around the problem with a components prop.

components?: {
  Root: React.ElementType<React.HTMLAttributes<HTMLDivElement>>;
  Label: React.ElementType<React.HTMLAttributes<HTMLSpanElement>>;
}

https://github.com/oliviertassinari/material-ui/blob/153c1833fb204a28ee6712db1c2ac6a9308a163e/packages/material-ui/src/TableCell/TableCell.unstyled.js#L18

The problem

I think that it would be great to defines which API works best and in which cases. I would hope that by doing so, we can provide a consistent experience for the developers using the library to build applications and websites. I also think that by reducing the number of approaches we can reduce the learning curve for new users.

When should we use a component, when should we use a render prop, etc.?

Prior-arts

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:8
  • Comments:22 (22 by maintainers)

github_iconTop GitHub Comments

5reactions
oliviertassinaricommented, Jun 22, 2022

flat vs. deep

@dmtrKovalenko While I think that we should encourage flatten props as much as possible for the reasons mentioned in https://github.com/mui-org/material-ui/issues/21453#issuecomment-656065074. (@dtassone Yes, I very much have the DataGrid API in mind the options could be flattened :p), It’s not without its limitations.

I see a couple of advantages in going deep:

  • As a developer, it makes it easier to find all the customization points (both when reading the docs and when in the editor with IntelliSense), you go look at the prop y, it’s one place, always the same between all the components. You don’t need to scan the whole set of props the component exposes. Take the Autocomplete, we have 59 props, take the DatePicker, we have 65 props, good luck if they aren’t prefixed with the same wording, like renderX or componentX.
  • It makes it easier to forward these props deep down the React tree, you forward one y prop, not all the props.
  • These are props you will likely not use frequently, likely for the first time you want to customize your component, then you can create an abstraction and reuse it.
  • It’s consistent with the classes prop.
3reactions
oliviertassinaricommented, Jun 22, 2022

Closing as we agreed on:

<MuiXXX
  components={{
    Root: SomeRootComponent,
    Label: SomeLabelComponent,
  }}
  componentsProps={{
    root: { someProp: 'some value' },
    label: { someProp: 'some value' },
  }}
/>

going forward.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[RFC] What's the best API to override deep/nested elements?
A while back, around the alpha & beta iterations on the v1 version, we had to decide what was the best way to...
Read more >
Registration Data Access Protocol (RDAP) Partial Response
The use of partial responses in RESTful API [REST] design is very common. The rationale is quite simple: instead of returning objects in...
Read more >
RFC 9205: Building Protocols with HTTP
Applications often use HTTP as a substrate to create HTTP-based APIs. This document specifies best practices for writing specifications that use HTTP to ......
Read more >
Return binary data via RFC - abap - Stack Overflow
If I understand well pyRFC, it's based on the API from NWRFCSDK, thus RfcGetBytes should do the job too. Answer: XSTRING.
Read more >
REST API Design Best Practices for Sub and Nested Resources
If we nest our resources, what should we keep in mind? Since this decision can have a considerable impact on many parts of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found