【问题标题】:React/Redux, updating store with mapDispatchToPropsReact/Redux,使用 mapDispatchToProps 更新存储
【发布时间】:2020-10-15 13:19:25
【问题描述】:

几乎完成了一个副项目,最后要修复的是按钮不起作用。
主要是参考this article 寻求指导,但出了点问题。

Store 部分看起来像这样(有一个并行进行的数据库调用,因此会出现 thunk,以防您想知道):

const initState = {
    ...
    total: 100
}

//actions
...
export const addToCart = sum => ({
    type: 'ADD_CART',
    payload: sum
})

//reducers
const reduceProducts = (state = initState, action) => {
    switch(action.type){
        ...
        case 'ADD_CART':
            return {
                total: state.total + action.payload
            };
        default:
            return state;
    }
}

...

//store
const store = createStore(
    reduceProducts, 
    applyMiddleware(thunk)
);

export default store;

有问题的组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import store, { addToCart } from '../store/store.js';
import { Navbar, Nav, NavItem, CardColumns, Card, Button } from 'react-bootstrap';
import { LinkContainer } from 'react-router-bootstrap';


//Navbar component
class App extends Component {

    ...

    render() {
        if (!this.props.products.length){
            return <div> Loading... </div>
        }
        return (
            ...
                    <Navbar.Collapse>
                        <Nav> 
                            <LinkContainer to="/cart">
                                <NavItem>{this.props.total}</NavItem>
                            </LinkContainer>
                            ...
                        </Nav>
                    </Navbar.Collapse>
                </Navbar>
                    <CardColumns>
                    {
                        this.props.products.map( item => { return <PizzaTable pizzas={item} key={item.id}/> }) 
                    }       
                    </CardColumns>
            </div>
        );
    }
}


//Cart component
class PizzaTable extends Component{
    handleCart = (e) =>{
        addToCart(e.target.id);
    }

    render(){
        return(
            <Card>
                ...
                <Button id={this.props.pizzas.price} onClick={this.handleCart}>{this.props.pizzas.price}</Button>
            </Card>
        );
    }
}

const mapStateToProps = state => ({
    ...
    total: state.total
})

export default connect(mapStateToProps, {addToCart})(App);

试图将所有不相关的代码保持在最低限度,数据库获取和渲染工作正常。

addToCart 函数在全局范围内可用,因此直接使用它,无需作为 prop 或绑定传递。

这应该如何工作:

  • 按钮被点击,handleCart 被激活。
  • 它采用 e.target.id(一个肯定是数字的值,console.logged)并将其传递给 addToCart。
  • addToCart 然后使用 mapDispatchToProps 的简写,调用操作,其中 e.target.id 是有效负载。
  • Reducer 将 e.target.id 添加到 total 并更新 NavItem 中的视图。

然而,在 mapDispatchToProps 区域的某个地方,正在传递的值正在丢失 - 将 addToCart 有效负载记录到存储中不会显示任何内容。 要么是我使用了错误的 dispatch,要么是忘记调用或返回一些明显的东西。

【问题讨论】:

  • 看起来PizzaTable 没有连接到您的 redux 商店。 App 是,但没有带有 onClick 处理程序的按钮来“addToCart”。
  • 连接中的{addToCart} 不是必需的,而是尝试this.props.dispatch(addToCart(e.target.id))

标签: reactjs redux


【解决方案1】:

PizzaTable 未连接到您的 redux 存储。看起来您错误地将其 addToCart 动作创建者连接到了 App

//Cart component
class PizzaTable extends Component{
  handleCart = (e) =>{
    addToCart(e.target.id);
  }

  render(){
    return(
      <Card>
        ...
        <Button
          id={this.props.pizzas.price}
          onClick={this.handleCart}
        >
          {this.props.pizzas.price}
        </Button>
      </Card>
    );
  }
}

const ConnectedPizzaTable = connect(null, { addToCart })(PizzaTable);

App 中,使用connected Pizza table 组件,并从其connect HOC 中移除addToCart

<CardColumns>
  {
    this.props.products.map(item => (
      <ConnectedPizzaTable pizzas={item} key={item.id}/>
    ) 
  }       
</CardColumns>

...

export default connect(mapStateToProps)(App);

【讨论】:

  • 不是错误的,App 是父组件,它接收所有的 props 和传入的数据库信息,然后,据说,将其传递给子 PizzaTable。所以我必须将每个子组件都连接到商店……明白了,谢谢!
  • @VladFedorov 是的,替代方案是“道具钻孔”,这实际上是 react-redux 的问题,通过实现,反应上下文 API 解决了。
猜你喜欢
  • 2017-07-10
  • 1970-01-01
  • 2019-02-11
  • 2021-10-10
  • 2016-01-13
  • 2020-08-01
  • 2020-07-14
  • 2019-12-19
  • 2021-05-06
相关资源
最近更新 更多