What is the best way to trigger actions from child components within React Redux?

My server contains the following code snippet:

<ReactRedux.Provider store={store}><Layout defaultStore={JSON.stringify(store.getState())}/></ReactRedux.Provider>

The <Layout> component includes more nested components.

Further down in my code, I have a class that looks like this:

import React from 'react';

export default React.createClass({
  render: function(){
    var classes = [
      'js-select-product',
      'pseudo-link'
    ];

    if (this.props.selected) {
      classes.push('bold');
    }

    return (
      <li className="js-product-selection">
        <span onClick={this.props.onClick} className={classes.join(' ')} data-product={this.props.id}>{this.props.name}</span>
      </li>
    );
  }
});

Instead of using this.props.onClick, I would like to dispatch an event to update the state in a reducer. I've come across some information online regarding context but there seems to be conflicting opinions on whether or not it is being deprecated.

EDIT I have found mention of this connect method, but I recall reading advice against using connect in child components.

Answer №1

Instead of focusing too much on children components, a better approach is to organize your app with connected and non-connected components. Non-connected components should be stateless, pure functions that receive all necessary data through props. Connected components, on the other hand, should utilize the connect function to link redux state and dispatcher to props, and then handle passing these props down to child components.

Your application may have numerous connected and non-connected components. For further insight into this design pattern, you can refer to this article (authored by the creator of redux), which delves deeper into the roles of non-connected (dumb) components for UI display and connected (smart) components for component composition.

Consider the following example (using newer syntax):

class Image extends React {
  render() {
    return (
      <div>
        <h1>{this.props.name}</h1>
        <img src={this.props.src} />
        <button onClick={this.props.onClick}>Click me</button>
      </div>
    );
  }
}

class ImageList extends React {
  render() {
    return (
      this.props.images.map(i => <Image name={i.name} src={i.src} onClick={this.props.updateImage} />)
    );
  }
}

const mapStateToProps = (state) => {
  return {
    images: state.images,
  };
};
const mapDispatchToProps = (dispatch) => {
  return {
    updateImage: () => dispatch(updateImageAction()),
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(ImageList);

In this scenario, ImageList functions as a connected component while Image serves as a non-connected component.

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

Basic Hover Effect in Javascript

Looking at this snippet of HTML: <div id="site-header-inner"> <div id="header-logo"> <?php echo wp_get_attachment_image(get_field('header_logo','options'),'full'); ?> </div> <div id= ...

The React application hosted on an nginx server is unable to establish a connection to the nodejs backend

After successfully launching my first React, Node, MongoDB, and Nginx application on EC2's free tier, I encountered an issue where the frontend API calls were not reaching each other despite the backend API working separately and the frontend running ...

Unable to place within div

Utilizing HTML5 to implement the "DnD" function. There is a button that adds divs. I want to be able to drag items into these newly added divs. Currently, I can only drag into existing divs and not the ones added later. How can I resolve this issue ...

Resolve issue with header in scrollable material-ui popover

Material-UI allows for a fixed header and footer in a Dialog with long, scrolling content. I am looking to achieve the same effect but within a popover. For example: <Popover> <Header>Fixed header</Header> <Content>long long ...

What could be the reason for the mismatch in size between the downloaded file in Express.js and the file size on the server?

My code using express.js is quite simple: app.get("/download", download); and export let download = async (req: Request, res: Response) => { const file = "/tmp/my-file.zip"; res.download(file); } The client-side code is also straightforward: im ...

What is the reason behind the android code being incompatible with IOS operating systems?

I'm encountering an issue where a particular code is working on Android, but not on IOS. The code in question involves using JavaScript to differentiate the items in a list within an HTML select tag. It's perplexing to me how the code can operat ...

Twitter API causing issues with setTimeout function in Node.js

Attempting to read from a file and tweet the contents in 140 character chunks, one after the other has proven to be quite challenging. Despite verifying that other parts of the code are functioning correctly, using a simple for-loop resulted in tweets bein ...

Customizing the Sorting of Bars in Apex Charts: A Step-by-Step Guide

I have implemented a horizontal Bar Chart using React Apex-Charts, and it currently looks like this: I would like to change the default sort order from Ascending to Descending, so that the bar with the highest value appears at the top and the smallest v ...

Leverage the power of conditional fetching with useSWR in combination with the versatile React-

Attempting to integrate YouTube comments into an infinite loading component (using an npm package for it). The issue arises because the infinite load component is a child of the parent Accordion component (from react-bootstrap), and my objective is to fet ...

"Encountering a KnexTimeoutError while utilizing the knex.transactionProvider() function

I am currently working on implementing Knex transactions into my project using the relevant files provided below. However, I am encountering the following error: KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you ...

Automatically pre-fill and send hidden form

I'm working on a form and have set up a handler for the submit button like this: $( '#submit_btn' ).click( function( data ){ theForm = document.getElementById( 'realForm' ); theForm.meetingName.value = document.getElement ...

Angular: Maximizing Input and Output

I'm having trouble with the function displaying within the input field. My goal is to simply allow the user to enter a name and have it displayed back to them. HTML: <div ng-app = "mainApp" ng-controller = "studentController"> <tr> < ...

The multiple-choice selection tool is not displaying any choices

I am having an issue with my ng-repeat code in conjunction with the jquery multiple-select plugin. Despite using this plugin for a multiple select functionality, the options generated by ng-repeat are not visible. Below is the code snippet in question: & ...

What could be causing my Vue.js sorting array script to malfunction?

I'm encountering an issue with sorting the table by Date. The sort function used to determine the type of sorting no longer works, and I'm unsure why. html: <th @click = "sort('data_produktu')" class="date">Da ...

Auto-fill input field with URL parameter values using JavaScript or jQuery

I am in possession of a URL http://www.example.com/state=survey&action=display&survey=39&zone=surveys&currency=Denmark Upon accessing the above link, a user will be directed to a new page containing a form. Within this form, there is an i ...

Enhance user experience by customizing login functionalities in Meteor using React: Integrate personalized

Currently, I am utilizing account-ui to incorporate a drop-down login feature in Meteor. However, I have encountered an issue where I am unable to expand user sign-up functionality to include First and Last Name fields. This is because Meteor account ui on ...

Using TypeScript to determine the week number - the value on the right side of the math operation must be of data type 'any'

I've spent a lot of time searching for code to help me calculate the week number in my Angular app according to ISO standards. It's been challenging to find JavaScript-specific code, but I believe I may have found something - however, I encounter ...

Fetching user feeds from Facebook with AngularJS is easier than you think

I have searched through multiple articles but have yet to find a solution for this particular issue. My goal is to retrieve user feeds from Facebook. How can I achieve this? Below is my code: var newMod = angular.module('newapp', []); newMod.c ...

Place a check mark in the corner of the button

I am looking to add a checkmark on my button in the right corner. I have set the input value and it displays a button with a check mark, but I want it to be positioned in the right corner. .buttoner{ background-color: #4CAF50; b ...

The element within the iterator is lacking a "key" prop, as indicated by the linter error message in a React component

Encountering an error stating Missing "key" prop for element in iteratoreslintreact/jsx-key {[...Array(10)].map((_) => ( <Skeleton variant="rectangular" sx={{ my: 4, mx: 1 }} /> ))} An attempt to resolve this issue was made ...