Skip to Content
Create A React List In Minutes With Vite MUI & Redux

Create A React List In Minutes With Vite MUI & Redux

Want to create a React list in minutes with Vite, MUI, and Redux? Awesome! This post will get you a list app up and running within minutes.

First, we’re going to introduce a new way to create a react app besides using CRA (Create React App). Instead of using CRA, we’ll be using Vite. Vite is a simple (and lightening fast) build tool, similar to Create React App but better!

Estimated reading time: 6 minutes

Create the app with Vite:

If you want to create a react app with Vite it couldn’t be simpler. Just open up a folder in your VS Code (or other IDE) and enter one of these commands in the terminal.

To create a React Typescript app

Enter the following command in your terminal. Note that you can change name-of-app to anything you want.

 npm create vite@latest name-of-app --template react-ts

If you don’t want to use Typescript:

 npm create vite@latest name-of-app --template react

Don’t forget to change directories into your app:

cd name-of-app

Install your dependencies

We’re going to build a list as quickly as possible. To create a React list in minutes with Vite, MUI, and Redux, we’ll make use of some super neat libraries.

We’re going to install the following dependencies:

  • reduxjs/toolkitsimplify common use cases like store setup, creating reducers, immutable update logic, and more.
  • react-redux provides APIs that enable your components to interact with the Redux store
  • faker jsa popular library that generates fake (but reasonable) data
  • material uioffers a comprehensive suite of UI tools to help you ship new features faster.
  • material ui icons 2,100+ ready-to-use React Material Icons from the official website.

Throw each of these into the terminal to install your dependencies:

npm install @reduxjs/toolkit  
npm install react-redux             
npm install @faker-js/faker --save-dev 
npm install @mui/material @emotion/react @emotion/styled
npm install @mui/icons-material

Create the following folders inside the src directory:

  • data
  • store
  • components

In the Data Folder

The data folder will house a function that will use faker js to generate random words for our list.

Inside the data folder create an index.ts file. Inside of that we’ll import faker:

import { faker } from "@faker-js/faker/locale/en"

Next we’re going to create a function and export it:

export const createRandomWords = () => {}

This function will return information from faker js. Essentially some random words.

export const createRandomWords = () => {
  return `${faker.word.adjective()} ${faker.word.noun()}`
}

We’ll be importing this function later in our MainList.tsx component.

In the Components Folder

We’re only going to need one new component. Inside of our components folder, we’ll create a file MainList.tsx.

Scaffold the MainList.tsx component

To create a React list in minutes, we should utilize the Material UI library to build our components. We won’t need to worry about building components from scratch, neither will we need to style them. We’ll start by importing our Material UI components.

import { Box, Button, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'
import DeleteIcon from '@mui/icons-material/Delete'

Next we’ll scaffold out the component:

function MainList() {

  const handleItemAdd = (item: string) => {
    console.log(item)
  }
  const handleItemRemove = (item: string) => {
    console.log(item)
  }

  const renderedList = randomWords.map((item: string) => {
    return (
      <ListItem disablePadding key={item}>
        <ListItemButton onClick={() => handleItemRemove('item')}>
              <ListItemIcon>
                <DeleteIcon color="primary" />
              </ListItemIcon>
              <ListItemText primary={item} />
          </ListItemButton>
      </ListItem >
    );
  });

  return (
    <Box sx={{ width: '100%' }}>
      <Button onClick={() => handleItemAdd('item')}>Add Random Item to list</Button>
      <List>
      {renderedList}
      </List>
      </Box>
  );
}
export default MainList

Currently this won’t work, so let’s import our data function and use that in the handleItemAdd event handler.

Want more React List projects? Check out this tutorial on how to build an Accessible React List.

First we’ll import the function at the top of the MainList.tsx file:

import { createRandomWords } from "../data"

Then we’ll use it in our MainList return statement where our Button component is:

<Button onClick={() => handleItemAdd(createRandomWords())}>Add Random Item to list</Button>

This isn’t going to work until we hook up our Redux store so let’s finish scaffolding the List and move on.

In the App.tsx file

Inside the App.tsx file, first import the MainList component:

import MainList from './components/MainList'

Next, replace everything in between the React fragment with the MainList component like so:

import MainList from './components/MainList'
import './App.css'

function App() {

  return (
    <>
       <MainList />
    </>
  )
}

export default App

In the Store Folder

Let’s create our Redux store so we can make this list app work. Inside the store folder, create an index.ts file. Import configureStore, and createSlice from reduxjs/toolkit:

import { configureStore, createSlice } from "@reduxjs/toolkit"

Create a slice like so:

const itemsSlice = createSlice({
  name: "list",
  initialState: [],
  reducers: {}
})

Create the store underneath this:

const store = configureStore({
    reducer: {
      items: itemsSlice.reducer
    }
  })

Now export the store:

 export { store }

In the main.tsx file

Before we complete our Redux store, we need to wrap our app in a Provider. The Redux store uses React Context under the hood to ensure the entire app has access to it. Navigate to the main.tsx file and import the Provider and the store like so:

import { Provider } from "react-redux"
import { store } from "./store"

Next, wrap the App component in the Provider and set the store prop to your Redux store.

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <Provider store={store}>
    <App />
    </Provider>
  </React.StrictMode>,
)

Want to learn how and when to use React Context? Check out our post here on Context vs Props.

Back inside the store/index.ts file we’re going to create our actions. These will be called by our button onClick events within the MainList.tsx component.

Inside the itemSlice component, add the following functions to your reducers object:

 reducers: {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    addItem(state: any, action: any) {

      // push will add the item to the end of the array
      state.push(action.payload)
    },
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    removeItem(state: any, action: any) {

      const index = state.indexOf(action.payload)

      // splice will remove the item from the array 
      // where the index of that item is
      state.splice(index, 1)
    }
  }

Next we’ll export these action creators so our app can use them. Place this destructuring export statement at the bottom of the store/index.ts file:

  export const { addItem, removeItem } = itemsSlice.actions

Finishing up the MainList.tsx component

Back in our MainList.tsx component let’s import the following:

import { useDispatch, useSelector } from "react-redux"
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { addItem, removeItem } from "../store"

Inside the MainList functional component, let’s create a constant called dispatch. This will be how we use the useDispatch hook:

  const dispatch = useDispatch()

Next we’ll extract data from our store using the useSelector hook from react-redux:

 const dispatch = useDispatch()
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const randomWords = useSelector((state: any) => {
    return state.items
  })

Finally, we can call dispatch and the addItem and removeItem actions respectively within our event handlers like so:

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const handleItemAdd = (item: any) => {
    dispatch(addItem(item))
  }
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const handleItemRemove = (item: any) => {
    dispatch(removeItem(item))
  }

Conclusion Now you’ve created a React list in minutes!

And that’s it. Check out the complete code here if you need it for reference and thanks so much for stopping by!

Photo by Christopher Gower on Unsplash