Friday, March 24, 2023

React CRUD application using the useReducer hook simple Example

Step 1: In this example, we define an initial state object that contains an empty array of items. 

Step 2: We also define a reducer function that handles the add, edit, and delete actions on the state. We use the useReducer hook to create a state object and a dispatch function that allows us to update the state by dispatching actions to the reducer function.

Step 3: The form in the render function allows us to add or edit items. When we submit the form, we dispatch an add or edit action to the reducer function, depending on whether we're adding a new item or editing an existing one. We also reset the name input field.

Step 4: The list of items is displayed as an unordered list. Each item is rendered as an li element with its name, an Edit button, and a Delete button. Clicking the Edit button sets the editItem state to the selected item and populates the name input field with its name. Clicking the Delete button dispatches a delete action to the reducer function with the item's ID as the payload.

Here is an example of a simple CRUD app that allows you to add, edit, and delete items in a list:

 

import React, { useReducer, useState } from 'react';

const initialState = {
  items: []
};

function reducer(state, action) {
  switch (action.type) {
    case 'add':
      return {
        items: [...state.items, action.payload]
      };
    case 'edit':
      return {
        items: state.items.map((item) => {
          if (item.id === action.payload.id) {
            return action.payload;
          }
          return item;
        })
      };
    case 'delete':
      return {
        items: state.items.filter((item) => item.id !== action.payload)
      };
    default:
      throw new Error();
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);
  const [name, setName] = useState('');
  const [editItem, setEditItem] = useState(null);

  const handleSubmit = (event) => {
    event.preventDefault();
    if (!name.trim()) {
      return;
    }
    if (editItem) {
      dispatch({ type: 'edit', payload: { ...editItem, name } });
      setEditItem(null);
    } else {
      dispatch({
        type: 'add',
        payload: { id: new Date().getTime(), name }
      });
    }
    setName('');
  };

  const handleEdit = (item) => {
    setEditItem(item);
    setName(item.name);
  };

  const handleDelete = (id) => {
    dispatch({ type: 'delete', payload: id });
  };
 
    return (
    <div>
      <h1>CRUD App</h1>
      <form onSubmit={handleSubmit}>
        <input
          type='text'
          placeholder='Enter name'
          value={name}
          onChange={(event) => setName(event.target.value)}
        />
        <button type='submit'>{editItem ? 'Edit' : 'Add'}</button>
      </form>
      <ul>
        {state.items.map((item) => (
          <li key={item.id}>
            {item.name}
            <button type='button' onClick={() => handleEdit(item)}>
              Edit
            </button>
            <button type='button' onClick={() => handleDelete(item.id)}>
              Delete
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;


 

React CRUD application using a useReducer hook for state management

 Step 1: First, we'll define our initial state and the action types that we'll use:

 

const initialState = {
  items: [],
};

const ADD_ITEM = "ADD_ITEM";
const DELETE_ITEM = "DELETE_ITEM";
const UPDATE_ITEM = "UPDATE_ITEM";
 

Step 2: Next, we'll define our reducer function:

 

function reducer(state, action) {
  switch (action.type) {
    case ADD_ITEM:
      return {
        ...state,
        items: [...state.items, action.payload],
      };
    case DELETE_ITEM:
      return {
        ...state,
        items: state.items.filter((item) => item.id !== action.payload),
      };
    case UPDATE_ITEM:
      return {
        ...state,
        items: state.items.map((item) =>
          item.id === action.payload.id ? action.payload : item
        ),
      };
    default:
      return state;
  }
}

In this reducer function, we handle three types of actions:

  • ADD_ITEM: adds a new item to the items array in state
  • DELETE_ITEM: removes an item from the items array in state based on its id
  • UPDATE_ITEM: updates an item in the items array in state based on its id

 Step 3: Now, let's create our main component, App, which will use the reducer to manage state:

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const addItem = (item) => {
    dispatch({ type: ADD_ITEM, payload: item });
  };

  const deleteItem = (id) => {
    dispatch({ type: DELETE_ITEM, payload: id });
  };

  const updateItem = (item) => {
    dispatch({ type: UPDATE_ITEM, payload: item });
  };

  return (
    <div>
      <ItemList items={state.items} deleteItem={deleteItem} updateItem={updateItem} />
      <AddItemForm addItem={addItem} />
    </div>
  );
}
 

In this App component, we use the useReducer hook to create a state object and a dispatch function to send actions to the reducer. We also define three callback functions (addItem, deleteItem, and updateItem) that will be passed down to child components.

 Step 4:Next, let's create the ItemList and AddItemForm components:

function ItemList({ items, deleteItem, updateItem }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          {item.name} ({item.quantity})
          <button onClick={() => deleteItem(item.id)}>Delete</button>
          <button onClick={() => updateItem(item)}>Edit</button>
        </li>
      ))}
    </ul>
  );
}

function AddItemForm({ addItem }) {
  const [name, setName] = useState("");
  const [quantity, setQuantity] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();
    const newItem = { name, quantity };
    addItem(newItem);
    setName("");
    setQuantity("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" value={name} onChange={(e) => setName(e.target.value)} />
      </label>
      <label>
        Quantity:
        <input type="number" value={quantity} onChange={(e) => setQuantity(e.target.value)} />
      </label>
      <button type="submit">Add Item</button>

 

 

Copyright @ 2013 React Tutorials.

Designed by Mathew | mathai