V
V
vovashaplin2020-05-17 16:32:11
React
vovashaplin, 2020-05-17 16:32:11

Why does a function from react-redux work in one component, but not in another?

I have the addItemToBasket function, which speaks for itself, in the general menu, adding to the basket works for me, and when I go to the product page, it no longer works there (I just take the id as the price)
MapState works fine and the ID is transferred in the component

HERE THE CODE OF THE PRODUCTS PAGE

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { fetchItems, setCurrentPage, addItemToBasket } from '../../store/actions/items'
import Loader from '../../components/UI/Loader/Loader'
import Paginator from '../../components/UI/Paginator/Paginator'
import Layout from '../Layout/Layout'
import Card from '../../components/Card/Card'

class Items extends Component {

    componentDidMount() {
        this.props.fetchItems(true)
    }

    pageChanged = (index) => {
        this.props.setCurrentPage(index)
        this.props.fetchItems(false)
    }


    render() {

        return (
            <Layout>
                <Paginator
                    totalItemsCount={this.props.totalItemsCount}
                    pageSize={this.props.pageSize}
                    currentPage={this.props.currentPage}
                    pageChanged={this.pageChanged}
                    portionSize={3}
                />
                <div className="card-group row">
                    {
                        this.props.loading || this.props.items.length === 0
                         ? <Loader />
                         : <Card 
                            items={this.props.items}
                            addItemToBasket={this.props.addItemToBasket}
                            />
                    }
                </div>
            </Layout>
        )
    }
}

function mapStateToProps(state) {
    return {
        items: state.items.items,
        loading: state.items.loading,
        pageSize: state.items.pageSize,
        totalItemsCount: state.items.totalItemsCount,
        currentPage: state.items.currentPage,
        portionSize: state.items.portionSize
    }
}

function mapDispatchToProps(dispatch) {
    return {
        fetchItems: (bool) => dispatch(fetchItems(bool)),
        setCurrentPage: (currentPage) => dispatch(setCurrentPage(currentPage)),
        addItemToBasket: (id) => dispatch(addItemToBasket(id))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Items)

HERE IS THE CODE OF THE CARD WHICH I PASS TO ADDITEMTOBASKET
import React from 'react'
import * as R from 'ramda'
import { Link } from 'react-router-dom'

const Card = ({items, addItemToBasket}) => {
    return items.map(item => {
        const shortDescription = `${R.take(60, item.email)}...`
        return (
            <div className="col-sm-6 col-lg-4 book-list" key={item.id}>
                <div className="card mb-3">
                    <img src={item.avatar} alt={item.first_name} className="card-img-top" />
                    <div className="card-body">
                        <strong className="pull-right">{item.last_name}</strong>
                        <h5 className="card-title">
                            <Link to={`/items/${item.id}`}>
                                {item.first_name}
                            </Link>
                        </h5>
                        <p>{shortDescription}</p>
                        <p className="itemButton">
                            <button 
                                className="btn btn-primary"
                                onClick={() => addItemToBasket(item.id)}
                            >Buy now</button>
                            <Link to={`/items/${item.id}`} className="btn ">
                                More info
                            </Link>
                        </p>
                    </div>
                </div>
            </div>
        )
    })
}

export default Card

THIS IS ACTION
import {
    ADD_ITEM_TO_BASKET
} from './actionTypes'
export function addItemToBasket(id) {
    return {
        type: ADD_ITEM_TO_BASKET,
        payload: id
    }
}

HERE IS THE REDUCER
import {ADD_ITEM_TO_BASKET} from '../actions/actionTypes'

const initialState = []

export default function busketReducer(state = initialState, action) {
    switch(action.type)
    {
        case ADD_ITEM_TO_BASKET:
            return [
                ...state, action.payload
            ]
        default:
            return state
    }
}

AND HERE IS THE SAME PRODUCT PAGE ON WHICH THE SAME DOES NOT WORK
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { fetchItemById, addItemToBasket } from '../../store/actions/items'
import Loader from '../../components/UI/Loader/Loader'
import { Link } from 'react-router-dom'
import BasketCart from '../../components/BasketCart/BasketCart'

class Item extends Component {

    componentDidMount() {
        this.props.fetchItemById(this.props.match.params.id)
    }

    renderSidebar() {
        return (
            <div className="mt-4">
                <BasketCart />
                <h1 className="display-4 mb-4">{this.props.item.first_name}</h1>
                <h1>{this.props.item.last_name}</h1>
                <button className="btn btn-primary btn-lg" onClick={() => addItemToBasket(this.props.item.id)}>Add to Cart</button>
            </div>
        )
    }

    render() {
        // console.log(this.props.item)
        return (
            <div className="container mt-3">
                <div className="row">
                    <div className="col-md-9">
                        <div>
                            <Link exact="true" to="/" className="btn btn-secondary mb-3">Вернуться назад</Link>
                            {!this.props.item || this.props.loading
                                ? <Loader />
                                :
                                <div className="jumbotron text-center">
                                    <img
                                        src={this.props.item.avatar}
                                        style={{ height: '250px' }}
                                        className="mb-4"
                                        alt={this.props.item.first_name}>
                                    </img>
                                    <p className="lead">{this.props.item.email}</p>
                                    <hr className="my-4"></hr>
                                </div>
                            }
                        </div>
                    </div>
                    <div className="col-md-3">
                        {this.props.item && this.renderSidebar()}
                    </div>
                </div>
            </div>

        )
    }
}

function mapStateToProps(state) {
    return {
        item: state.items.item,
        loading: state.items.loading
    }
}

function mapDispatchToProps(dispatch) {
    return {
        fetchItemById: (id) => dispatch(fetchItemById(id)),
        addItemToBasket: (id) => dispatch(addItemToBasket(id))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Item)

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question