score:18

Accepted answer

With the hooks provided by react-redux since v7.1.0, this can be now written without mapStateToProps and mapDispatchToProps.

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';


const Rubrics = () => {
  const dispatch = useDispatch();

  const { rubrics, loading, error } = useSelector(
    state => ({
      error: state.error,
      rubrics: state.rubrics,
      loading: state.loading
    })
  );

  useEffect(() => {
    dispatch(fetchRubrics());
  }, [dispatch]);

  if (error) { return <div>Error! {error.message}</div>; }
  if (loading) { return <div>Loading...</div>; }

  return (
    <ul>
      <React.Fragment>
        {rubrics.map(rubric => {
          return (
            <li key={rubric.id}>{rubric.title}</li>
          );
        })}
      </React.Fragment>
    </ul>
  )
};

score:1

Below is the correct code:

const Rubrics = (props) => {

    useEffect(() => {
        props.fetchAllRubrics();
    }, [])


    return (
        props.rubrics.map((rubric) => {
            return (<RubricCard rubric={rubric} />)
        })
    )
}

const mapStateToProps = state => ({
    error: state.error,
    rubrics: state.rubrics,
    loading: state.oading
})

const mapDispatchToProps = dispatch => {
    return { fetchAllRubrics: () => dispatch(fetchRubricsData()) }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Rubrics);

score:2

In your dispatch mapping you have

const mapDispatchToProps = (dispatch) => {
    return {
        getRubrics: () => dispatch(fetchRubrics())
    };
}

so instead of calling props.dispatch(fetchRubrics()); just call props.getRubrics() or destructurize this method from props

const { rubrics, loading, error, getRubrics } = props;

and just call getRubrics()

score:5

The problem here is that you are using incorrectly mapDispatchToProps. You don't need to set explicitly the dispatch function, that is what react redux does for you.

So, below is the correct way to do it:

// Now you won't be creating a new object every time your component re-renders
const mapDispatchToProps = {
  getRubrics: fetchRubrics
}

const Rubrics = (props) => {    
  const { getRubrics } = props;

  // You should always add elements inside your render scope
  // to the second array parameter of useEffect to prevent unexpected bugs.
  useEffect(() => {
      getRubrics();
  }, [getRubrics]);

  return (    
    <div>Your component here!</div>
  )
}

Related Query

More Query from same tag