2
votes

In my CRUD application, I am facing a problem every time the initial state ( array list ) updates with a new entry.

Clicking on an add button should open a modal and fill out a react-hook-form. On submit should update the state by adding the new entry. Clicking on the edit button should open a modal and load data to the react-hook-form. On submit should update the state by updating the corresponding entry.

Everything works fine until I add a new entry in the state. The entry is displayed in the table and clicking the edit button of that or any other entry works fine. When clicking the button of any entry, again the isEdit state stops to change as it should. I have a working demo here

In App.js These are the states in the application. One for users list, one for distinguishing between add and update functions, and the last for passing the default values to the form when updating a user.

const [users, setUsers] = useState([]);
const [isEdit, setIsEdit] = useState(false);
const [defaultValues, setDefaultValues] = useState(initialDefaultValues);

There is a list of users coming from a GET request. When the request resolves successfully, I set the returned data to the state.

// get Users
  const fetchUsers = async () => {
    const res = await fetch("https://jsonplaceholder.typicode.com/users");
    const resData = await res.json();
    if (res.status === 200) {
      setUsers(resData);
    } else {
      alert(resData);
    }
  };

  // execute on component render
  useEffect(() => {
    fetchUsers();
  }, []);

There is a component that renders a react-bootstrap-table-next and takes the data from the state.

<UsersTable
  data={users}
  prepareUpdateUser={prepareUpdateUser}
  prepareDeleteUser={prepareDeleteUser}
/>

This table has two buttons for each entry. An edit button and a delete button. On click these buttons the two prepare functions are executed accordingly (prepareUpdateUser, prepareDeleteUser). This is the code for the prepareUpdateUser(). The function takes the user as an argument, changes the isEdit state to true, updates the defaultValues to pass to the react-hook-form, and finally opens the modal.

const prepareUpdateUser = (user) => {
    setIsEdit(true);
    setDefaultValues({
      id: user.id,
      name: user.name,
      email: user.email
    });
    toggleUserModal();
  };

When the modal close, I reset the isEdit and `defaultValues`` state to their initial values.

const [userModal, toggleUserModal] = useModali({
    animated: true,
    title: isEdit ? "Update User " : "Add User ",
    onHide: () => {
      isEdit && setIsEdit(false);
      setDefaultValues(initialDefaultValues);
    }
  });

The problem is that after adding a new entry in the state and then try to click the edit button of any entry, everything works, but the next time you click the button the isEdit state stops updating every time the modal closes, and each time the prepareUpdateUser runs. The problem does not appear when updating an entry.

This is the code to add a new user to the users list

const addUser = (data) => {
 const newArray = users.slice();
 newArray.splice(0, 0, data);
 setUsers(newArray);
 toggleUserModal();
};

This is the code to update a user

const updateUser = (data) => {
 const updatedUser = users.findIndex((user) => user.email === data.email);
 const newArray = users.slice();
 newArray[updatedUser] = data;
 setUsers(newArray);
 toggleUserModal();
};

If you are going to use the demo link, here are the steps to reproduce the problem.

  1. Click on any edit button. Everything loads and the isEdit state is true.
  2. Click the add button. The form is empty and the isEdit state is false.
  3. Add a new entry.
  4. The list updates with the new entry.
  5. Click an edit button. Seems to work.
  6. Click again an edit button and now isEdit is false and no data loaded in the form

Has anyone faced something similar? I am fairly new to react, and I cannot understand why this happens. Any advice will be really helpful.

Thank you all in advance.

1

1 Answers

1
votes
**I have just modified below block of code**

 const prepareUpdateUser = (user) => {   
setIsEdit(true);
setDefaultValues({
  id: user.id,
  name: user.name,
  email: user.email
});
 };

  **Newly added one useEffect**
useEffect(() => {
if (isEdit) {
  toggleUserModal();
}
}, [isEdit]);

try this. Please give your valuable feedback