Guide to creating a custom wrapper for a Material UI component with React JS

I am utilizing the Material UI next library for my project and currently working with the List component. Due to the beta version of the library, some parameter names are subject to change. To prevent any future issues, I have decided to create a wrapper around the necessary components. Here is my current list component:

<List dense>
   <List className={classes.myListStyles}>
      <ListItem disableGutters/>
   </List>
</List>

How can I create a wrapper for the List (let's call it myListWrapper) and ListItem so that the wrapper component can manage props and pass them down to the actual Material UI list component?

Answer №1

During a recent project, I delved into MUI wrappers and crafted my own library to streamline the process. The main focus was on efficiently passing props from our wrapper component to the inner/actual MUI components with some manipulation involved - especially when abstracting props.

Below outlines my unique approach to finding a solution:

import { List as MaterialList } from 'material-ui/List';
import { React } from 'react';
import { ListItem as MaterialListItem } from 'material-ui/ListItem';

class List extends MaterialList {
    constructor(props){
        const propsToPass = {
            prop1: change(props.prop1),
            ...props
        }
        super(propsToPass);
    }
};

class ListItem extends MaterialListItem {
    const propsToPass = {
            prop1: change(props.prop1),
            prop2: change(props.prop2),
            ...props
        }
        super(propsToPass);
    }
};


class App extends React.Component {
    render () {
        return (
            <List prop='value' >
                <ListItem prop1={somevalue1} prop2={somevalue2} />
                <ListItem prop1={somevalue1} prop2={somevalue2} />
                <ListItem prop1={somevalue1} prop2={somevalue2} />
            </List>
        )
    }
};

The code snippet above facilitates several useful features for your components:

  • You can utilize props with identical names used in Material UI.
  • You have the ability to manipulate/change/transform/reshape the passed props from external sources.
  • If the props provided to your wrapper components share the same names as those used by MUI, they will automatically pass through to the inner component. (Using the spread operator.)
  • To avoid confusion, you can use Component names that match those of Material UI.
  • The code adheres to advanced JSX and JavaScript ES6 standards.
  • You are given the flexibility to adjust your props before passing them to MUI Components.
  • Additionally, you can implement type checking using propTypes.

If you encounter any uncertainties or queries, feel free to reach out.

Answer №2

You might want to structure it as follows:

const CustomList = props => (
    <List 
        {/*include prop values here*/}
        customPropA={props.A}
        customPropB={props.B}
    >
        {props.children}
    </List>
)

const CustomListItem = props => (
    <ListItem 
        {/*include prop values here*/}
        customPropA={props.A}
        customPropB={props.B}
    >
        {props.children}
    </ListItem>
)

To make use of CustomList and CustomListItem, define the prop names for these components (as per your preference), and within these components, map those values to corresponding Material-UI component properties.

Note:

If you opt to use the same prop names (matching material-ui component expectations) for your components, you could simplify things like this:

const MyList = ({children, ...rest}) => <div {...rest}>{children}</div>

const MyListItem = ({children, ...rest}) => <p {...rest}>{children}</p>

Consider this illustration:

const X = props => <div>{props.children}</div>

const Y = props => <p>{props.children}</p>

ReactDOM.render(
  <X>
    <X>
      <Y>Greetings</Y>
    </X>
  </X>,
  document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app' />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adding a div element to a React component with the help of React hooks

I'm currently diving into the world of React and experimenting with creating a todo app to enhance my understanding of React concepts. Here's the scenario I'm trying to implement: The user triggers an event by clicking a button A prompt app ...

Encountering a problem while trying to launch the development server for a React application using the npm-start

I followed the steps to create a react application using npx create-react-app myapp, but when I use npm start, it fails to start a developer server. Even after trying to reinstall the node_modules, the issue persists. I am using the latest versions of Reac ...

Tips on personalizing MUI X Data Grid Toolbar to exclusively display icons

`function EnhancedToolbar() { return ( <GridToolbarContainer> <GridToolbarIcon icon={<FilterListIcon />} /> <GridToolbarIcon icon={<ViewColumnIcon />} /> <GridToolbarIcon icon={<SettingsEthernetIc ...

Ways to execute a function when clicking on a date using HTML 5 datepicker input type

How can I call a function in angular js when a date is selected from an html5 date-time picker using a mouse click? I need help with this. Here is the HTML code: <div class="col-lg-4"> <input class="form-control" type="datetime" date-time auto ...

Encountered a 500 internal server error while attempting to establish a connection between React

Encountering a 500 internal server error while trying to connect React with MongoDB using axios. Despite several attempts, the issue persists. Seeking assistance in resolving this matter. ...

The element is not defined in the Document Object Model

There are two global properties defined as: htmlContentElement htmlContentContainer These are set in the ngAfterViewInit() method: ngAfterViewInit() { this.htmlContentElement = document.getElementById("messageContent"); this.htmlContentCont ...

Tips on altering the color of a circle's radius within Google Maps

I'm trying to add a circular radius on a Google Map. Even after reviewing the Google Maps API documentation, I'm still unsure of how to accomplish this task. Below is the code snippet I have been working with: const MyMapComponent = compose( ...

Error: The module you are trying to import from the package is not found. Please check the package path and make sure that

I encountered an issue when trying to compile a code in Reactjs. As a beginner in Reactjs, I'm struggling with this. Module not found: Error: Package path ./cjs/react.development is not exported from package /Users/mansi/letsgrowmore/to-do-list/my-rea ...

How to achieve a gradual border or box-shadow transition from thick to slim using CSS

Is there a way to achieve the design shown in the image below? I am looking for a thick top border that gradually becomes thinner as it reaches the sides and seamlessly merges into the black block. https://i.stack.imgur.com/gmjQh.png Here is my CSS code ...

What is the best way to ensure these 2 divs are aligned vertically in the provided html (starting at the same vertical level)?

<div class="container"> <div class="row"> <div class="col-lg-12"> <div class="news-title"> <h3 class="title">NEWS & ARTICLES</h3> ...

Leveraging the wheelDelta property in the onmousewheel event handler with Script#

When working with Script#, I often utilize mouse events using the ElementEvent argument. However, one thing seems to be missing - the WheelDelta property for handling the onmousewheel event. Can anyone provide guidance on how to access this property in t ...

Ensure that all divs have the same height and padding when resizing

I have 3 divs nested within a parent div. My goal is to dynamically set the height of all the child divs to match the height of the div with the maximum height, even when the screen resizes due to responsiveness. Below is my HTML structure: <div class ...

Using async/await in combination with Vuex and Feathers

Please review my code below. I am attempting to integrate Async Await into vuex. While everything is functioning properly, I would like to call another action after this one using async await. However, the expected result is not being achieved as the conso ...

Tips for creating a custom hook that is type safe:

When I use the custom function createUser, I've noticed that I can pass numbers instead of strings without receiving an error. Surprisingly, even if I forget to include an argument, no red squiggles appear. const [userState, createUser] = useCre ...

Redirecting asynchronously in Node.js with no use of AJAX

I've been struggling with this issue for days and have already sought help, but nothing seems to be working. Whenever I attempt to redirect from a POST request in node, the browser doesn't respond. Here's how my app is structured: ./ confi ...

Sorting through an array of objects using a filter method

While following a tutorial, I decided to make some changes to the TypeScript for learning purposes. However, I encountered a problem when trying to create a filter function from a React context script. I have successfully implemented a function called get ...

Establish a background image that can be scrolled

Currently, I am working on a project and have created a fiddle that can be accessed here: https://jsfiddle.net/0g3u8452/1/ The image I am using is 1920x4000, and I want it to span the full width of the screen similar to setting background-size ...

Persistent hover effect for collapsible accordion panels when closing them

My simple accordion features a functionality where a class of .open is added to the title + content group when you open a panel for styling purposes. Everything works smoothly, but I've noticed on my phone that after clicking to close a panel, the hov ...

Every time I try to retrieve my JavaScript code, I am bombarded with endless prompts that prevent me

Desperate for assistance! I have been using a website called "codepen" for my javascript coding, but I mistakenly triggered infinite prompts every time I open the project. Now, I am unable to access the code and despite my efforts in searching for a solu ...

Utilizing AngularJS ng-repeat, generate dynamic HTML content by calling a function to retrieve data

Just starting out with angularjs and trying to unravel the mystery here. Using ng-repeat: <li class="widget flip-container" ng-repeat="widget in widgets"> <div class="widgetContent" ng-bind-html="getData(widget.UserWidgetId,widg ...