Retrieve the current state within a redux action

Many experts recommend consolidating the logic in action creators to streamline the reducer's logic.

Picture a basic (normalized) state:

const initialState = {
  parent: {
    allIds: [0],
    byId: {
      0: {
        parentProperty: `I'm the parent`,
        children: [1, 2]
      }
    }
  },
  children: {
    allIds: [1, 2],
    byId: {
      1: {
        childrenProperty: `I'm the children`
      },
      2: {
        childrenProperty: `I'm the children`
      }
    }
  }
}

If I were to delete the parent, I would also need to delete the associated children.

An example of an action creator for this scenario:

function removeParent(parentId) {
  return {type: 'REMOVE_PARENT', payload: {parentId}};
}

and

function removeChild(childId) {
   return {type: 'REMOVE_CHILD', payload: {childId}};
}

Currently, my approach with redux-thunk looks like this:

function removeParentAndChildren(parentId) {
  return (dispatch, getState) {
    const childrenIds = getChildIds(getState(), parentId);
    const childActions = childrenIds.map(removeChild);
    const combinedAction = combineActions([
      removeParent(parentId),
      ...childActions
    ], 'REMOVE_PARENT_AND_CHILDREN');
    dispatch(combinedAction);
  }
}

This method allows me to bundle smaller actions into one larger action, keeping the reducer logic straightforward by simply removing keys from objects.

On the flip side, using redux-thunk just for retrieving state information is frowned upon as an anti-pattern.

How do you handle similar challenges? Could tools like redux-saga be beneficial in this context?

Answer №1

It appears that the issue you are facing is quite prevalent, especially in more complex applications. I recommend considering utilizing redux-orm, although it may be challenging to grasp initially and integrate into your project. However, once configured, it simplifies the process of managing relationships between entities.

Answer №2

In my opinion, a different approach is needed in this situation. My suggestion would be to remove the child while deleting the parent without dispatching the child_delete action. By creating a new state during the deletion of the parent in the reducer, you can also access and remove the children associated with that parent from the state.

If you still prefer to dispatch actions separately, you can pass child IDs from the component to the action. Then, within that action, you can dispatch two distinct actions - one for deleting the parent and another for deleting the children by their IDs.

----------- REVISION -------

// The current application's initial state
const initialState = {
  parent: {
    allIds: [0],
    byId: {
      0: {
        parentProperty: `I am the parent`,
        children: [1, 2]
      }
    }
  },
  children: {
    allIds: [1, 2],
    byId: {
      1: {
        childrenProperty: `I am a child`
      },
      2: {
        childrenProperty: `I am a child`
      }
    }
  }
}

export default function batchManagement(state = initialState, action) {
  switch (action.type) {
    case 'DELETE_PARENT':  //assuming action.deleteParents = [0]
      // Modify parents and children or create a completely new state here since you have access to the state
    case 'DELETE_CHILDREN':
      // Provide a new object for the state
    default:
      return state;
  }
}

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

Creating a dynamic text field integrated with Google Places in Ionic 4: a step-by-step guide

I am currently implementing the google-place-api autoComplete feature in my project, but I encountered an error: TypeError: Cannot read property 'getInputElement' of undefined .html <section [formGroupName]="i" *ngFor="l ...

What is the process for passing external JSON data to a task from a file that was generated in a previous task?

Currently facing an issue with the following setup in my Gruntfile: grunt.initConfig({ shell: { // stub task; do not really generate anything, just copy to test copyJSON: { command: 'mkdir .tmp && cp stub.json .tmp/javascript ...

How can I deactivate the main color of the FormLabel when the focus is on the radio button group?

Is there a way to change the color of FormLabel to black instead of the primary color when the radio button group is focused? const styles = { formLabel: { color: "#000" }, formLabelFocused: { color: "#000" } }; function App({ classes } ...

Sending a function return to a React component

What I want to achieve is sending the response from an API call to a React Component and using it to generate a List. My confusion lies in how to pass the value from a function to the component. Do I require state for this process? searchMealsHandler(even ...

Unexpected behavior with Node js event listener

I am currently working on emitting and listening to specific events on different typescript classes. The first event is being listened to properly on the other class, but when I try to emit another event after a timeout of 10 seconds, it seems like the lis ...

Troubleshooting issue with jQuery animate not correctly scrolling

I am experiencing an issue with my jQuery code that is supposed to scroll a smaller container element within a larger container element when a button is clicked. Despite testing with an alert and verifying that the code is working, the scrolling functional ...

Highlight the navigation transition in the menu

Is there a more updated tutorial available for creating an underline effect that slides from one link to another when hovered over and remains at the clicked link? I have come across a tutorial on Underline transition in menu which seems to be based on th ...

Integrating Javascript and JQuery in Reactjs: A Comprehensive Guide

Currently, I am working with ReactJS and utilizing the Next.js framework. My goal is to implement the provided code snippet in index.js to display data (day, month, etc.). How should I go about achieving this? Here is the code snippet: <script> fun ...

Having Issues with Material-UI Lists Rendering?

I am having an issue with rendering a list of posts on the index page. I can successfully create posts by clicking the 'Add Post' button and submitting the form on the /posts/new route. However, the list of posts is not showing up on the index pa ...

Internet Explorer: JQuery deselects radio button upon its selection

One issue I have encountered is with a listener for a group of radio buttons in IE. When a radio button is selected, it triggers a database call to populate a select element. However, in IE, after the code runs successfully, the selected radio button becom ...

AngularJS $http.get('') is throwing an error because some parameters are missing

I am currently working on an application that utilizes OAuth for authentication, but I am facing some issues with passing the URL parameters correctly. Despite trying various methods, my API keeps returning an error stating that the username and password a ...

Synchronization issues arise when attempting to update the localStorage

Whenever I switch to dark mode, the update doesn't reflect in _app unless I have two tabs opened and trigger it in one tab. Then, the other tab gets updated with dark mode toggled, but not the tab where I pressed the toggle. I am using useSettings in ...

What is the best way to obtain the attribute value when a user clicks on a child element?

Is there a way to retrieve the value of the data-custom attribute when the red square is clicked without having to add the same attribute to nested elements? This can become cumbersome if there are multiple levels of nesting. class Example extends React ...

creating a Vue app using Node results in an HTML page with no content due to syntax errors

After creating a VueJs page using the CLI, I wanted to share it with others who might not have Vue CLI or Node installed. Just like opening .html files in a browser, I tried to open the index.html file after building it. However, when I opened the file, a ...

Retrieve specific information from checkboxes within a form

I'm working on a form that includes multiple checkboxes populated with data from a JSON file using ng-repeat. After submitting the form, I need to retrieve the data from the checked checkboxes. How can I accomplish this in my controller after the form ...

AngularJS application failing to initialize without a module being included

I'm feeling a bit lost when it comes to angularjs and I have a question about why my angularjs app is refusing to bootstrap without creating a module, even though egghead.io and other tutorials seem to suggest otherwise. Here's a snippet of my HT ...

What is the best way to achieve line breaks in text that auto-wraps in JavaScript/PHP?

My resizable div contains text/sentences. As I adjust the size of the div, the text wraps itself to perfectly fit within the available space in the container div. Now, I am faced with the task of converting this dynamic text into an image using php and th ...

Using $nin alongside $and in Mongoose

Implementing a filter for an admin user using mongoose operations. The user should be able to view all saved files except for those that are classified as draft files. However, the admin user should still have access to their own saved draft files. Code ...

The ng-model directive in drop-down selection elements

I have a series of questions along with their answers, and I want the user to select an answer from a drop-down menu. How can I achieve this? I've attempted the following code, but the select option isn't appearing on the screen. HTML: <div ...

How to deactivate the <a> tag with Ant Design UI Library

Is there a method in the antd UI library to disable a link? The disabled attribute is not supported by the a tag according to MDN. This code snippet works in React but the link remains clickable when using Next.js. <Tooltip title={tooltip}> <a ...