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]
1 menjawab
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>