D
D
Dmitry2019-04-15 18:24:28
React
Dmitry, 2019-04-15 18:24:28

Why is dispatch not firing?

Hello, there is a component

ProductTabs

import React, {Component} from 'react';
import ReactHtmlParser from "react-html-parser";
import {validateEmail} from '../../../../helpers/validation';
import Tabs from './Tabs';
import ProductComments from '../../../ProductComments';

import {connect} from 'react-redux';
import {setProductComments} from '../../../../actions/products';

class ProductTabs extends Component {

    constructor(props){
        super(props);
        this.state = {
            comments: [],
            users: {},
            commentsLength: 0,
            /* states for creating new comment */
            productCommentContent: '',
            productSlug: this.props.productSlug,
            productID: this.props.productID,
            userID: null,
            userName: '',
            userEmail: '',
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentDidMount(){

        const {productSlug} = this.props;

        axios.get(`/api/product-comments/${productSlug}`).then(data => {

            console.log( data.data.allComments );

            setProductComments(data.data.allComments);

            console.log( 'this.props', this.props );

            let {allComments, allUsers} = data.data;
            const users = allUsers.reduce((acc, el) => (
                acc[el.id] = el, acc
            ), {});

            /*
            if current user is logged out -> userID is id of the guest user users.id = 11
            while authorization does not work the variable is declared here
            */
            const USER_ID = this.state.userID ? this.state.userID : 11

            this.setState({
                comments: allComments,//is Array
                users: users,// is Object
                userID: USER_ID,
                // if current user is logged out then userName is empty string
                // is for empty string validation before send request to server
                userName: (USER_ID === 11) ? '' : users[USER_ID]['name'],
                userEmail: users[USER_ID]['email'],
                userLogo: users[USER_ID]['logo'],
                commentsLength: allComments.length ? allComments.length : 0,
            });
        });
    }

    handleChange(e){
        this.setState({
            [`${e.target.name}`]: e.target.value,
        });
    }

    handleSubmit(e){
        e.preventDefault();

        if ( this.state.productCommentContent && validateEmail(this.state.userEmail) && this.state.userName ) {
            const productComment = {
                content: this.state.productCommentContent,
                product_slug: this.state.productSlug,
                product_id: this.state.productID,
                user_id: this.state.userID,
                user_name: this.state.userName,
                user_email: this.state.userEmail,
            }

            axios.post('/api/product-comments', productComment).then(response => {
                const newCommentsList = [...this.state.comments, response.data];
                this.setState({
                    comments: newCommentsList,
                    commentsLength: newCommentsList.length,
                });
            });
        }
    }

    render(){
        const {tabBg, descr, ingredients, usage, title } = this.props;

        return (
            <Tabs tabBg={tabBg}>
                {descr && (
                    <div title="Описание">
                        {ReactHtmlParser(descr)}
                    </div>
                )}

                {ingredients && (
                    <div title="Состав">
                        {ReactHtmlParser(ingredients)}
                    </div>
                )}

                {usage && (
                    <div title="Применение">
                        {ReactHtmlParser(usage)}
                    </div>
                )}

                <div title={`Отзывы (${this.state.commentsLength})`}>
                    <ProductComments
                        title={title}
                        state={this.state}
                        handleChange={this.handleChange}
                        handleSubmit={this.handleSubmit}
                    />
                </div>
            </Tabs>
        );
    }
}

const mapStateToProps = state => {

    console.log( state );

    return {
        comments: state.products.comments
    };
};

const mapDispatchToProps = dispatch => ({
    setProductComments
});

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

action

import { FETCH_PRODUCTS, FETCH_PRODUCTS_SUCCESS, SET_CATEGORY_FILTER } from './types';

export const setProducts = products => ({
    type: 'SET_PRODUCTS',
    payload: products
});

export const setProductSingle = product => ({
    type: 'SET_PRODUCT_SINGLE',
    payload: product
});

export const setProductComments = comments => ({
    type: 'SET_PRODUCT_COMMENTS',
    payload: comments
});

export const CategoryFilters = {
    SHOW_ALL: 'SHOW_ALL',
    BESTSELLER: 'BESTSELLER',
    FACE: 'FACE',
    BODY: 'BODY',
    SCRUB: 'SCRUB',
};

reducer

import { SET_PRODUCTS, SET_IS_READY, FETCH_PRODUCTS, FETCH_PRODUCTS_SUCCESS, FETCH_RECCOMENDED_PRODUCTS, FETCH_RECCOMENDED_PRODUCTS_SUCCESS } from '../actions/types';

const INITIAL_STATE = {
    isReady: false,
    isSingleReady: false,
    isCommentsReady: false,
    items: [],
    product: {},
    comments: [],
};

export default function (state = INITIAL_STATE,action){
    switch (action.type) {
        case SET_PRODUCTS:
            return {
                ...state,
                items: action.payload,
                isReady: true
            };
        case 'SET_PRODUCT_SINGLE':
            return {
                ...state,
                product: action.payload,
                isSingleReady: true
            };
        case 'SET_PRODUCT_COMMENTS':

            console.log( 'dadada' );

            return {
                ...state,
                comments: action.payload,
                isCommentsReady: true,
            };
        case SET_IS_READY:
            return {
                ...state,
                isReady: action.payload
            };
        default:
            return state;
    }
}

props.products.commentsI end up with a default value. Debugged action and reducer, they all receive and return the required arrays, but in the end it is empty.
What could be the problem? Thank you.
PS: in the component itself so far through the state - it is in the process of being reworked.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2019-04-15
@ddimonn8080

Why is dispatch not firing?

Because you don't call it.
Replace the line: with: or with:
To make the first option work, change mapDispatchToProps:
const mapDispatchToProps = {
  setProductComments,
};

You also import action types into actions and reducers, but write strings in type in hardcode. Do not do it this way.
It is customary to make requests to the API in async actions.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question