ddimonn8080
@ddimonn8080

Почему dispatch не срабатывает?

Здравствуйте, есть компонент
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.commentsв итоге имею значение по умолчанию. Дебажил action и reducer все они получают и возвращают нужные массивы но в итоге пусто.

В чем может быть проблема? Спасибо.

PS: в самом компоненте пока через state - он в процессе переделки.
  • Вопрос задан
  • 511 просмотров
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Почему dispatch не срабатывает?


Потому что вы его не вызываете.

Замените строку:
setProductComments(/* ... */);
на:
this.props.setProductComments(/* ... */);
или на:
this.props.dispatch(setProductComments(/* ... */));

Чтобы первый вариант работал, измените mapDispatchToProps:
const mapDispatchToProps = {
  setProductComments,
};


Еще вы импортируете в actions и reducer типы действий, но пишите в type строки хардкодом. Не надо так.
Запросы к API принято выносить в async actions.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы