Saya mencoba menambahkan tindakan "addProduct" ke komponen. Tapi saya melihat kesalahan ketika saya mengkliknya, bantu saya mengatasinya, terima kasih sebelumnya!

Saya tidak mengerti di mana kesalahan saya (

import { bindActionCreators } from "redux";
import { addProduct } from "../actions/addProduct";

const ProductListItem = ({ product }) => {
  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} />;
  });


const mapDispatchToProps = dispatch => {
  return bindActionCreators({ addProduct }, dispatch);
};

connect(null,
  mapDispatchToProps
)(ProductListItem);
[enter image description here][1]
3
Anon 2 Juni 2019, 23:20

1 menjawab

Jawaban Terbaik

Untuk menambahkan tindakan Anda dengan benar, Anda perlu memetakan pengiriman ke komponen Anda, menggunakan fungsi koneksi redux.

function connect(mapStateToProps?, mapDispatchToProps?, ...)

Parameter pertama digunakan untuk memetakan state ke props.

const mapStateToProps = state => {
    return { products: state.products, cart: state.cart };
};

const Item = connect(mapStateToProps)(MyItemComp)

Sekarang di komponen Anda, Anda memiliki akses ke products dan cart sebagai props. Yang dapat Anda akses menggunakan this.props.products

Parameter kedua digunakan untuk mengizinkan komponen Anda mengirimkan tindakan.

function mapDispatchToProps(dispatch) {
  return {
    addProduct: e => dispatch(addProduct(e))
  };
}

const Item = connect(mapStateToProps, mapDispatchToProps)(MyItemComp)

Sekarang kita dapat mengirimkan tindakan dari komponen kita, dengan menjalankan addProduct(product).

Connect dapat digunakan seperti

// 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)

Sekarang mari perbaiki komponen Anda

 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>
  );
};

Perubahan

export default ({ products = [] }) =>
  products.map((product, i) => {
  return <ProductListItem key={i} product={product} />;
});

Untuk

// export ProductListItem
export default ({ products = [], addProduct }) =>
  products.map((product, i) => {
    return <ProductListItem key={i} product={product} addProduct={addProduct}/>;
});

Sekarang kita perlu melampirkan props dan dispatcher

// import the above export
import ProductListItem from './ProductListItem';

const ProductList = connect(
  mapStateToProps,
  mapDispatchToProps
)(ProductListItem);

Di komponen induk Anda

render() {
  ...
  return(
    <div>
      ...
      <ProductList />
      ...
    </div>
   )
}

DEMO

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.0.3/react-redux.min.js"></script>
<script src="http://wzrd.in/standalone/uuid%2Fv1@latest"></script>
<link
      href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
      rel="stylesheet"
      integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
      crossorigin="anonymous"
    />
<style>
  .product {
     display: flex;
     flex-direction: row;
     border-bottom-style: solid;
     margin-bottom: 5px;
     margin-top: 10px;
   }

   img.product_img {
     width: 30px;
   }

   .badge {
     padding-left: 9px;
     padding-right: 9px;
     -webkit-border-radius: 9px;
     -moz-border-radius: 9px;
     border-radius: 9px;
    }

    .label-warning[href],
    .badge-warning[href] {
      background-color: #c67605;
    }
    #lblCartCount {
      font-size: 12px;
      background: #ff0000;
      color: #fff;
      padding: 0 5px;
      vertical-align: top;
      margin-left: 1px;
    }
 </style>
    
 <div id="root"></div>
    
<script type="text/babel">
const { Provider, connect } = ReactRedux;
const { applyMiddleware, createStore, combineReducers } = Redux;

function addProduct(payload) {
  return { type: 'ADD_PRODUCT', payload };
}

const initialState = {
  products: [
    {
      id: 1,
      name: 'Avocado',
      price: 1.5,
      image: 'https://img.icons8.com/metro/26/000000/avocado.png',
      quantity: 0
    },
    {
      id: 6,
      name: 'Bread',
      price: 1,
      image: 'https://img.icons8.com/metro/26/000000/bread.png',
      quantity: 0
    },
    {
      id: 2,
      name: 'Milk',
      price: 1.8,
      image: 'https://img.icons8.com/metro/26/000000/milk-bottle.png',
      quantity: 0
    }
  ],
  cart: []
};

function rootReducer(state = initialState, action) {
  if (action.type == 'ADD_PRODUCT') {
    return {
      ...state,
      cart: [...state.cart, action.payload]
    };
  }
  return state;
}

const store = createStore(rootReducer);

const mapStateToProps = state => {
  return { products: state.products, cart: state.cart };
};

function mapDispatchToProps(dispatch) {
  return {
    addProduct: e => dispatch(addProduct(e))
  };
}

const CartItems = ({ cart }) => {
  return (
    <div>
      <i class="fa fa-shopping-cart" />
      <span class="badge badge-warning" id="lblCartCount">
        {cart.length}
      </span>
    </div>
  );
};

const ProductListItem = ({ product, addProduct }) => {
  return (
    <div className="product">
      <img className="product_img" src={product.image} />
      <p>{product.name}</p>
      <p style={{ marginLeft: 5, marginRight: 5 }} className="bold">${product.price}</p>
      <button className="add_card" onClick={() => addProduct(product)}>
        {' '}
        add to cart
      </button>
    </div>
  );
};

const Cart = connect(mapStateToProps)(CartItems);
const Products = ({ products = [], addProduct }) =>
  products.map((product, i) => {
    return <ProductListItem key={i} product={product} addProduct={addProduct}/>;
  });

const ProductList = connect(
  mapStateToProps,
  mapDispatchToProps
)(Products);

class App extends React.Component {
  render() {
    return (
      <div>
        <Cart />
        <ProductList />
      </div>
    );
  }
}
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
</script>
6
Junius L. 3 Juni 2019, 12:38