Javascript 如何使用Redux和ReactJS向功能组件添加操作

Javascript 如何使用Redux和ReactJS向功能组件添加操作,javascript,reactjs,redux,Javascript,Reactjs,Redux,我尝试将操作“addProduct”添加到组件中。但当我点击它时,我看到一个错误,请帮助我处理,提前谢谢 我不明白我的错误在哪里( 从“redux”导入{bindActionCreators}; 从“./actions/addProduct”导入{addProduct}; const ProductListItem=({product})=>{ 返回( {product.name} ${product.price} 添加产品(产品)}> {" "} 添加到购物车 ); }; 导出默认值({pro

我尝试将操作“addProduct”添加到组件中。但当我点击它时,我看到一个错误,请帮助我处理,提前谢谢

我不明白我的错误在哪里(

从“redux”导入{bindActionCreators};
从“./actions/addProduct”导入{addProduct};
const ProductListItem=({product})=>{
返回(
{product.name}

${product.price}

添加产品(产品)}> {" "} 添加到购物车 ); }; 导出默认值({products=[]})=> products.map((产品,i)=>{ 返回; }); const mapDispatchToProps=调度=>{ 返回bindActionCreators({addProduct},dispatch); }; 连接(空, mapDispatchToProps )(产品清单项目); [在此处输入图像描述][1]
我做了一些更新,并举例说明了我正在做的事情

  • 看起来您需要从
    react redux
  • 现在你需要从你的道具中解构
    addProduct
    您已使用
    mapDispatchToProps
  • 我重新定义了
    mapDispatchToProps
    以不使用
    bindActionCreators
    , 这只是偏好的问题,但两者都应该起作用
  • 在您的
    connect()
    中,我使用
    …rest
    并将其作为道具传播到返回的通道中
  • 父母亲
    您可能对动作创建者的格式进行了修改,使其成为普通对象,而不是返回对象的函数。

    要正确添加动作,您需要使用redux connect函数将分派映射到组件

    function connect(mapStateToProps?, mapDispatchToProps?, ...)
    
    第一个参数用于将状态映射到道具

    const mapStateToProps = state => {
        return { products: state.products, cart: state.cart };
    };
    
    const Item = connect(mapStateToProps)(MyItemComp)
    
    现在在您的组件中,您可以访问
    产品
    购物车
    作为道具。您可以使用
    此.props.products

    第二个参数用于允许组件分派操作

    function mapDispatchToProps(dispatch) {
      return {
        addProduct: e => dispatch(addProduct(e))
      };
    }
    
    const Item = connect(mapStateToProps, mapDispatchToProps)(MyItemComp)
    
    现在,我们可以通过执行
    addProduct(product)
    从组件中分派操作

    连接可以像这样使用

    // will only access props, won't dispatch any actions
    const Item = connect(mapStateToProps)(MyItemComp)
    // dispatch actions, won't access props
    const Item = connect(null, mapDispatchToProps)(MyItemComp)
    // will access props and dispatch actions
    const Item = connect(mapStateToProps, mapDispatchToProps)(MyItemComp)
    
    现在,让我们修复您的组件

     import { addProduct } from "../actions/addProduct";
     import { connect } from "react-redux";
    
    // add addProduct as a second parameter, to be able to dispatch actions from here
    const ProductListItem = ({ product, addProduct }) => {
      return (
        <div className="product">
          <img className="product_img" src={product.image} />
          <p>{product.name}</p>
          <p className="bold">$ {product.price}</p>
          <button className="add_card" onClick={() => addProduct(product)}>
           {" "}
           add to cart
          </button>
        </div>
      );
    };
    
    render() {
      ...
      return(
        <div>
          ...
          <ProductList />
          ...
        </div>
       )
    }
    
    在父组件中

     import { addProduct } from "../actions/addProduct";
     import { connect } from "react-redux";
    
    // add addProduct as a second parameter, to be able to dispatch actions from here
    const ProductListItem = ({ product, addProduct }) => {
      return (
        <div className="product">
          <img className="product_img" src={product.image} />
          <p>{product.name}</p>
          <p className="bold">$ {product.price}</p>
          <button className="add_card" onClick={() => addProduct(product)}>
           {" "}
           add to cart
          </button>
        </div>
      );
    };
    
    render() {
      ...
      return(
        <div>
          ...
          <ProductList />
          ...
        </div>
       )
    }
    
    render(){
    ...
    返回(
    ...
    ...
    )
    }
    
    演示

    
    .产品{
    显示器:flex;
    弯曲方向:行;
    边框底部样式:实心;
    边缘底部:5px;
    边缘顶部:10px;
    }
    img.product\u img{
    宽度:30px;
    }
    .徽章{
    左侧填充:9px;
    右侧填充:9px;
    -webkit边界半径:9px;
    -moz边界半径:9px;
    边界半径:9px;
    }
    .label警告[href],
    .badge警告[href]{
    背景色:#c67605;
    }
    #lblCartCount{
    字体大小:12px;
    背景:#ff0000;
    颜色:#fff;
    填充:0 5px;
    垂直对齐:顶部;
    左边距:1px;
    }
    const{Provider,connect}=ReactRedux;
    const{applyMiddleware,createStore,combineReducers}=Redux;
    功能添加产品(有效负载){
    返回{type:'ADD_PRODUCT',payload};
    }
    常量初始状态={
    产品:[
    {
    id:1,
    名称:“鳄梨”,
    价格:1.5,
    图像:'https://img.icons8.com/metro/26/000000/avocado.png',
    数量:0
    },
    {
    id:6,
    名字:'面包',
    价格:1,,
    图像:'https://img.icons8.com/metro/26/000000/bread.png',
    数量:0
    },
    {
    id:2,
    名字:“牛奶”,
    价格:1.8,
    图像:'https://img.icons8.com/metro/26/000000/milk-bottle.png',
    数量:0
    }
    ],
    购物车:[]
    };
    函数rootReducer(state=initialState,action){
    if(action.type==“添加产品”){
    返回{
    ……国家,
    购物车:[…state.cart,action.payload]
    };
    }
    返回状态;
    }
    const store=createStore(rootReducer);
    常量mapStateToProps=状态=>{
    返回{products:state.products,cart:state.cart};
    };
    功能图DispatchToprops(调度){
    返回{
    addProduct:e=>dispatch(addProduct(e))
    };
    }
    常量CartItems=({cart})=>{
    返回(
    {cart.length}
    );
    };
    const ProductListItem=({product,addProduct})=>{
    返回(
    {product.name}

    ${product.price}

    添加产品(产品)}> {' '} 添加到购物车 ); }; const Cart=connect(mapStateToProps)(CartItems); constproducts=({Products=[],addProduct})=> products.map((产品,i)=>{ 返回; }); const ProductList=connect( MapStateTops, mapDispatchToProps )(产品); 类应用程序扩展了React.Component{ render(){ 返回( ); } } ReactDOM.render( , document.getElementById('root')) );
    TypeError:addProduct不是function@Anon,啊,这很有意义,您没有在connect()中显式返回ProductListItem。而是使用.map返回它们的数组。当您这样做时,动作创建者不会作为道具显式传递。实际上,我从未见过有人在connect()中这样做.你能试试我上面更新的答案并告诉我是否有效吗?:)是的,我试了…现在我看到TypeError:Object(…)不是function@Anon,嗯,我在本地运行这个,它看起来像预期的那样工作。我已经更新了上面的解决方案,以展示我正在做的事情的一个快速示例。你能告诉我你的代码有什么不同吗?这个
    constproducts=[1,2,3]
    不应该存在吗?connect的第一个参数应该是一个函数。通常称为MapStateTops,它从您的状态返回数据并使其在组件中可用props@Anon,解决这个问题有什么进展吗?:o
     import { addProduct } from "../actions/addProduct";
     import { connect } from "react-redux";
    
    // add addProduct as a second parameter, to be able to dispatch actions from here
    const ProductListItem = ({ product, addProduct }) => {
      return (
        <div className="product">
          <img className="product_img" src={product.image} />
          <p>{product.name}</p>
          <p className="bold">$ {product.price}</p>
          <button className="add_card" onClick={() => addProduct(product)}>
           {" "}
           add to cart
          </button>
        </div>
      );
    };
    
    export default ({ products = [] }) =>
      products.map((product, i) => {
      return <ProductListItem key={i} product={product} />;
    });
    
    // export ProductListItem
    export default ({ products = [], addProduct }) =>
      products.map((product, i) => {
        return <ProductListItem key={i} product={product} addProduct={addProduct}/>;
    });
    
    // import the above export
    import ProductListItem from './ProductListItem';
    
    const ProductList = connect(
      mapStateToProps,
      mapDispatchToProps
    )(ProductListItem);
    
    render() {
      ...
      return(
        <div>
          ...
          <ProductList />
          ...
        </div>
       )
    }