reactjsreduxmapdispatchtoprops

OnClick event in React not working in child component


I read "Learning React" (Alex Banks and Eve Porcello) and try to write a simple Color Organizer App not like in a book.

Presently I have such a code structure in StarRating component.

import React from "react";
import Star from "../components/Star";

import { connect } from "react-redux";
import { rateColor } from "../redux/actions";

const StarRating = ({ currentColor, totalStars, rateColor }) => {
  return (
    <div className="star-wrapper">
      <div className="star-rating">
        {[...Array(totalStars)].map((key, i) => {
          return (
            <Star
              key={i}
              selected={i < currentColor.rating}
              onClick={() => rateColor(currentColor.id, i + 1)}
            />
          );
        })}
      </div>
      <div className="star-stats">
        {currentColor.rating} of {totalStars}
      </div>
    </div>
  );
};

const mapDispatchToProps = dispatch => {
  return {
    rateColor: (id, rating) => dispatch(rateColor(id, rating))
  };
};

export default connect(
  null,
  mapDispatchToProps
)(StarRating);

Add and remove reducers are work good but rate reducer not working. I need when I clicked on an asterisk - to change the value of selected stars...but nothing is happened.

A peice of "colors" reducers:

case RATE_COLOR:
      return {
        colors: [...state.colors.map(c => color(c, action))]
      };

and "color" reducer:

case RATE_COLOR:
      return state.id !== action.payload.id
        ? state
        : { ...state, rating: action.payload.rating };

All code is available here - https://codesandbox.io/s/color-organizer-react-62ubu?file=/redux/reducers/color.js


Solution

  • Your Star component doesn't have an onClick. Make sure to pass click handler from StarRating component to Star component.

    Working demo

    Star Rating component

    <div className="star-rating">
            {[...Array(totalStars)].map((key, i) => {
              return (
                <Star
                  key={i}
                  selected={i < currentColor.rating}
                  // onClick={() => rateColor(currentColor.id, i + 1)} // remove this
                  rateStarClick={() => rateColor(currentColor.id, i + 1)}
                />
              );
            })}
    

    Star component

    const Star = ({ selected = false, rateStarClick }) => {
      return (
        <div
          onClick={rateStarClick}
          className={selected ? "star selected" : "star"}
        />
      );
    };