How to set array into state onclick redux form - arrays

I am using a wizard in my project. In step 2 I have one form with a data table. The purpose of a data table is when I click on the button a form value pushes into a data table. I have done this when I submit the form, a form value append or push into a data table but I am facing an issue is that I can't maintain or set the state of that a data table array.
My code is shown below
import React, {useState, Fragment} from 'react';
import PropTypes from 'prop-types';
import { Field, FieldArray, reduxForm } from 'redux-form'
import FormInput from './../FormInput'
import ConsigneeTables from './ConsigneeTables'
import {
Button,
Card,
CardBody,
Col,
FormGroup,
Input,
Label,
Row,
Table,
Progress
} from 'reactstrap'
const ConsigneeLocations = (props) => {
const {handleSubmit, previousPage} = props
const consigneeData = []
const initialFormState = {
id: null,
consignee_branch_number: '',
consignee_add1: '',
}
const [CurrentConsignee, setCurrentConsignee] = useState(initialFormState)
const [consignees, setConsignees] = useState(consigneeData)
const [consignee, setConsignee] = useState(initialFormState)
const handleInputChange = (event) => {
const {name, value} = event.target
setConsignee({
...consignee,
[name]: value
})
}
const addConsignee = () => {
consignee.id = consignees.length + 1
console.log(consignee);
consignees.push(consignee)
setConsignees([...consignees])
}
return (<form onSubmit={handleSubmit}>
<h2>View users</h2>
<ConsigneeTables consignees={consignees}/>
<Col xs="12" sm="12">
<Card className="card-border">
<CardBody>
<Col xs="12" sm="12">
<Card className="card-border">
<CardBody>
<FormGroup row>
<Col xs="12" lg="6">
<Field name="consignee_branch_number" type="text" component={FormInput} value={consignee.consignee_branch_number} onChange={handleInputChange} label="Branch Sr No" inputPlaceHolder="Enter Branch Sr No"/>
</Col>
<Col xs="12" lg="6">
<Field name="consignee_add1" type="textarea" component={FormInput} value={consignee.consignee_add1} onChange={handleInputChange} label="Address 1" inputPlaceHolder="Enter Address 1"/>
</Col>
</FormGroup>
</CardBody>
<div style={{
paddingBottom: 30
}}>
<Button color="primary" className="btn-pill pull-right" type="button" onClick={addConsignee} style={{
marginRight: '20px'
}}>
Add
</Button>
</div>
</Card>
</Col>
<div style={{
paddingBottom: 30
}}>
<Button color="primary" className="btn-pill pull-left" onClick={previousPage} style={{
marginLeft: '20px'
}}>
<i className="fa fa-chevron-left"/>
Previous
</Button>
<Button color="primary" className="btn-pill pull-right" type="submit" style={{
marginRight: '20px'
}}>
Next
<i className="fa fa-chevron-right"/>
</Button>
</div>
</CardBody>
</Card>
</Col>
</form>);
};
ConsigneeLocations.propTypes = {
handleSubmit: PropTypes.func,
pristine: PropTypes.bool,
previousPage: PropTypes.func,
submitting: PropTypes.bool
};
export default reduxForm({form: 'consigneesLocation', destroyOnUnmount: false, forceUnregisterOnUnmount: true})(ConsigneeLocations);
My data table component
import React from 'react'
const ConsigneeTables = props => (
<table>
<thead>
<tr>
<th>Branch Number</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{props.consignees.length > 0 ? (
props.consignees.map(consignee => (
<tr key={consignee.id}>
<td>{consignee.consignee_branch_number}</td>
<td>{consignee.consignee_add1}</td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No Data</td>
</tr>
)}
</tbody>
</table>
)
export default ConsigneeTables
Please suggest to me how to handle consignees state. I already use setState onClick but I don't know how to handle consignees state every step.

Related

React.JS Object passing during onclick event

I am new to react,
I am using card, when card "on click" i need to get the card object and place it in form dynamically,
(full code)
My code:
// reactstrap components
import {useState} from "react"
import {
Card,
CardHeader,
CardBody,
CardTitle,
Col,
Input,
FormGroup,
Form,
Container,
Row,
UncontrolledDropdown,
DropdownToggle,
DropdownItem,
DropdownMenu,
Button,
} from "reactstrap";
import Header from "components/Headers/Header.js";
import 'react-toastify/dist/ReactToastify.css';
import Navbar from "components/Navbars/modulenavbar"
import axios from "axios";
import React from "react";
import { Link } from "react-router-dom";
var apitoken= localStorage.getItem('apitoken');
const api=axios.create({baseURL:"https://api/v1/account"})
const options = {
headers: {'Authorization': apitoken}
}
const Accounts = () => {
const [accounts, setaccount] = React.useState([]);
const [loading, setLoading] = React.useState(true);
const [disabled, setDisabled] = useState(false);
React.useEffect(async () => {
const response = await api.get("/",options);
setaccount(response.data.response);
setLoading(false);
}, []);
if (loading) {
return <>Loading...</>;
}
function handleGameClick() {
setDisabled(!disabled);
}
This is were i get all my api value and append it
return (
<>
{accounts.map((student, index) => {
const { id, name, phone, email } = student //destructuring
return (
<>
<div style={{ width: "18rem" }} onClick={() => console.log(student)}>
I want to pass the object "Student" and use it in the default value of the forms shown below
<Card className="card-stats mb-4 mb-lg-1">
<CardBody>
<Row>
<div className="col">
<CardTitle className="h4 font-weight-bold mb-0">
{name}
</CardTitle>
<span className="h5">{phone}</span>
</div>
<div className="col">
<span className="h5">{email}</span>
</div>
</Row>
</CardBody>
</Card>
</div>
</>
)
})}
</>
)
}
Form Shows here
const Display = () => {
return (
<>
<Header />
<Container className="mt--7" fluid>
{/* Table */}
<Row>
<Col className="order-xl-1 " xl="2">
<CardHeader className="bg-white border-0">
<Row className="align-items-center">
<Col xs="8">
<Link to="/admin//accounts" className="ni ni-bold-left">
<span> View Account</span></Link>
</Col>
</Row>
</CardHeader>
<Card className="bg-secondary shadow navbar-nav-scroll">
<Accounts/>
</Card>
</Col>
<Col className="order-xl-1" xl="10">
<Card className="bg-secondary shadow">
<Navbar/>
<Row >
<Col className="shadow navbar-nav-scroll">
<Form>
<h6 className="heading-small text-muted mb-4">
Account Information
</h6>
<div className="pl-lg-4">
<Row>
<Col >
<FormGroup>
<label
className="form-control-label"
htmlFor="input-username"
>
Account Name
</label>
<Input
className="form-control-alternative"
id="input-username"
placeholder="Username"
type="text"
defaultValue={student.value}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col >
<FormGroup>
<label
className="form-control-label"
htmlFor="input-email"
>
Email address
</label>
<Input
className="form-control-alternative"
id="input-email"
placeholder="jesse#example.com"
type="email"
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col >
<FormGroup>
<label
className="form-control-label"
htmlFor="input-email"
>
Phone
</label>
<Input
className="form-control-alternative"
id="input-phone"
placeholder="Phone"
type="text"
/>
</FormGroup>
</Col>
</Row>
</div>
</Form>
</Col>
<Col xs="9">
<Card className="card-stats mb-4 mb-lg-0">
<CardBody>
<div>
<Row className="align-items-center">
<Col xs="8">
</Col>
<Col className="text-right" xs="4">
<Button
color="success"
href="#pablo"
// onClick={save}
>
Save
</Button>
</Col>
</Row>
</div>
</CardBody>
</Card>
</Col>
</Row>
</Card>
</Col>
</Row>
</Container>
</>
);
};
export default Display;
Note:The above three sections of code is in the single component
I just want to dynamically append the values from object during "on click" event
Thanks in advance
You can store the clicked student value in state and pass it on to whichever component needs it as props
const Accounts = () => {
const [selectedStudent, setSelectedStudent] = useState({});
...
const handleStudentClick = (student) => {
setSelectedStudent(student)
}
return (
<>
{accounts.map((student, index) => {
const { id, name, phone, email } = student //destructuring
return (
<>
<div style={{ width: "18rem" }} onClick={() => handleStudentClick(student)}>
Now you can pass selected student as props to your child component

How to handle reusable components in React?

I'm trying to make a reusable input component. When data enters I want to handle those input data in the same place where I use that reusable input component. Not passing that as props.
I'm getting an error
Uncaught TypeError: Cannot read property 'value' of undefined
Can anyone give me any idea about how to handle data in such an instance?
InputFieldWithImage.js
import React, {useState} from "react";
import { Form, FormGroup, Input } from 'reactstrap';
function InputFieldWithImage(props) {
const [inputType] = useState(props.type)
const [inputValue, setInputValue] = useState('')
function handleChange(event){
console.log("Input.js");
console.log(inputValue);
setInputValue(event.target.value);
if(props.onChange) props.onChange(inputValue)
}
return (
<>
<Input type={inputType} value={inputValue} name="input-form" onChange={handleChange} class="inputclass"/>
</>
);
}
export default InputFieldWithImage;
AddTicket.js
import { Row, Col } from 'reactstrap';
import { Form, FormGroup, Input } from 'reactstrap';
import ActionButton from './../../components/ButtonComponent';
import InputFieldWithImage from './../../components/InputField/InputFieldWithImage'
import { render } from 'react-dom';
import ReactQuill from 'react-quill';
const AddTicket = (props) => {
const [assignee, setAssignee] = useState('');
const handleSubmit = (evt) => {
evt.preventDefault();
console.log('Assignee:' + assignee);
props.handleClose();
};
const test = () => {
console.log("text");
console.log('Assignee:' + assignee);
};
return (
<div className="popup-box">
<div className="box">
{/* <span className="close-icon" onClick={props.handleClose}>
x
</span> */}
<Form onSubmit={handleSubmit} style={{paddingLeft:30,paddingTop:50}}>
<Row style={{ paddingBottom: 50 }}>
<Col sm={11} xs={11} md={11}>
<h1>Add new ticket </h1>
</Col>
<Col onClick={props.handleClose} m={1} xs={1} md={1}>
<h1 className="close-icon">X </h1>
</Col>
</Row>
<FormGroup>
<Row style={{ marginBottom: '25px' }}>
<Col sm={2}>
<h4>Assignee</h4>
</Col>
<Col sm={2}>
<InputFieldWithImage value={assignee} onChange={(e) => setAssignee(e.target.value)} />
</Col>
</Row>
</FormGroup>
<Row>
<Col sm={2}></Col>
<Col>
<ActionButton text="Send" />
</Col>
</Row>
</Form>
</div>
</div>
);
};
export default AddTicket;
You need to pass event instead of inputValue . As there is input.target.value . That's why its giving error
function handleChange(event) {
console.log("Input.js");
console.log(inputValue);
setInputValue(event.target.value);
if (props.onChange) props.onChange(event);
}
Here is demo: https://codesandbox.io/s/hidden-tree-vr834?file=/src/App.js

React add new item to a table

I'm working on a React project. I need to add new data to a table using a form. In here when I run 'npm start' command it will show 'Audi' in the list. But when I trying to add new vehicle brand it will not adding. There are no errors showing. Can anyone solve this problem.
This is my vehicleType.jsx file
import React, { Component } from "react";
import { Button } from "reactstrap";
import {FormGroup,Form,Input,Col} from "reactstrap";
class VehicleType extends Component {
constructor(props){
super(props);
this.state = {
items : ['Audi']
}
}
addItem(e){
e.preventDefault();
const {items} =this.state;
const newItem = this.newItem.value;
this.setState({
items : [...this.state.items,newItem]
})
}
render() {
const { items } = this.state;
return (
<>
<Form onSubmit={(e) => {this.addItem(e)}}>
<Row>
<Col md="3">
<FormGroup className="has-success">
<Input ref={(input) => this.newItem =input } className="is-valid" placeholder="Add" type="text"/>
</FormGroup>
</Col>
<Col md="4">
<Button color="primary" size="lg" type="submit" >
Add new vehicle brand
</Button>
</Col>
</Row>
</Form>
<Table className="align-items-center" responsive>
<tbody>
{
items.map(item => {
return(
<tr key = {item}>
<th scope="row" col-md-2>
<span className="mb-0 text-sm">
{item}
</span>
</th>
</tr>
)}
}
</tbody>
</Table>
</>
);
}
}
export default VehicleType;
I think it's some issue with the reactstrap on the ref they provide here is the working sandbox for your requirement
sandbox
if you still need to use reactstrap then you need to go with state variable like
<Input onChange={handleInputChange} value={this.state.addValue} className="is-valid" placeholder="Add" type="text"/>
in the handleChange add this
handleInputChange(e){
this.setState({addValue:e.target.value})
}
Try this
addItem(e){
e.preventDefault();
const {items} =this.state;
items.push(this.newItem.value)
this.setState({ items })
}

How to open the file upload dialogue box When I click the Icon

I am working on a React project, In that I have a card, In the card I have react icon so what
I am trying to do is If I click the react icon, then file upload dialogue box has to open
please someone help to achieve this I am using Reactstrap for this
This is my code Form.js
import React, { useState, useRef } from 'react';
import './Form.css';
import { MdCloudUpload } from 'react-icons/md';
import { Row,Col,Button,Modal,ModalBody,ModalFooter } from 'reactstrap'
const Form = () => {
const inputFile = useRef(null)
const onButtonClick = () => {
inputFile.current.click();
};
return (
<Row>
<Col md="6" sm="6" xs="6">
<Modal isOpen={true}
>
<ModalBody>
<Row>
<Col md="4" sm="4" xs="4">
<div className="image-upload">
<input type='file' id='file' ref={inputFile} style={{ display: 'none' }}/>
<MdCloudUpload onClick={onButtonClick} className=' icon'></MdCloudUpload>
</div>
</Col>
<Col md="8" sm="8" xs="8">
</Col>
</Row>
</ModalBody>
<ModalFooter>
<Button color="secondary">
Cancel
</Button>
<Button type="submit" color="primary">
Submit
</Button>
</ModalFooter>
</Modal>
</Col>
</Row>
)
}
export default Form
there is two options:
use side library like react-dropzone
just add <input type="file" /> and trigger change event it when icon is clicked
here is an example
import React, { useState } from "react";
import "./Form.css";
import { MdCloudUpload } from "react-icons/md";
const Form = () => {
const onIconClick = () => {
const input = document.getElementById('file-input');
if (input) {
input.click();
}
};
return (
<Row>
<Col md="6" sm="6" xs="6">
<Modal isOpen={true}>
<ModalBody>
<Row>
<Col md="4" sm="4" xs="4">
<div className="image-upload">
<MdCloudUpload
className="icon"
onClick={onIconClick}
/>
<input
type="file"
id="file-input"
style={{ display: 'none' }}
/>
</div>
</Col>
<Col md="8" sm="8" xs="8" />
</Row>
</ModalBody>
<ModalFooter>
<Button color="secondary">Cancel</Button>
<Button type="submit" color="primary">
Submit
</Button>
</ModalFooter>
</Modal>
</Col>
</Row>
);
};
export default Form;

I want to collect some data from a form on one component and show it on other

I am trying to collect some details on component and show it on another component in short 2 page. But I don't know what's wrong it collects the data but won't show on the next component redux store, action reducers everything thing is created. Can someone tell me what am I doing wrong or something I am missing?
Thank you
GetDetail.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
import * as Actions from '../Actions/Action'
class GetDetails extends Component{
constructor(props, context){
super(props, context);
this.state={
details:{
name:"",
price:"",
company:"",
manufacture:"",
expiry:""
}
};
this.HandleSubmit = this.HandleSubmit.bind(this);
}
HandleSubmit() {
this.props.SubmitDetails(this.state.details);
}
render(){
return(
<div className="container" >
<form>
<h1>Enter Details Here</h1>
<div className="form-group">
<label>Name</label>
<input type="text" className="form-control" id="inputEmail4" placeholder="Email"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {name: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group">
<label >Price</label>
<input type="text" className="form-control" id="inputAddress" placeholder="1234 Main St"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {price: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group">
<label >Company</label>
<input type="text" className="form-control" id="inputAddress2"
placeholder="Apartment, studio, or floor"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {company: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group">
<label >Type</label>
<select id="inputState" className="form-control">
<option selected>Choose...</option>
<option>New</option>
<option>Used</option>
</select>
</div>
<div className="form-group ">
<label >Expiry Date</label>
<input type="text" className="form-control" id="inputCity"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {manufacture: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group ">
<label>Manufacture Date</label>
<input type="text" className="form-control" id="inputZip"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {expiry: e.target.value})})}
value={this.state.text}/>
</div>
<button type="submit" className="btn btn-primary" value="Save" onClick={this.HandleSubmit}>Submit</button>
</form>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return {
SubmitDetails: details => dispatch(Actions.SubmitDetails(details))
}
}
export default connect(mapDispatchToProps) (GetDetails);
ShowDetails.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
class ShowDetails extends Component{
diplayDetails(details, index){
return (
<tr key={index}>
<td>{details.name}</td>
<td>{details.price}</td>
<td>{details.company}</td>
<td>{details.price}</td>
<td>{details.expiry}</td>
<td>{details.manufacture}</td>
</tr>
)
}
render(){
return(
<div className="container2">
<h1> Show Details </h1>
<table className="table">
<thead className="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Company</th>
<th scope="col">Type</th>
<th scope="col">Expiry</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
{this.props.detail.map(this.diplayDetails)}
</tbody>
</table>
</div>
);
}
}
function mapStateToProps(state) {
return{
detail: state.detail
};
}
export default connect (mapStateToProps) (ShowDetails);
Reducers.js
export default function productReducer(state=[], action) {
switch (action.type) {
case 'ADD_PRODUCT':
return[...state,
Object.assign({}, action.details)
];
default:
return state;
}
}
index.js for rootreducers
import {combineReducers} from 'redux';
import ProductReducer from './Reducers';
const rootReducer = combineReducers({
detail: ProductReducer
});
export default root
Actions.js
export function SubmitDetails(details) {
return{ type: 'ADD_PRODUCT',details }
}
Alright, a lot of tweaks, but to summarize:
All this.setState() calls should be made in a class method.
connect() requires 2 parameters: mapStateToProps and mapDispatchToProps... if not utilizing mapStateToProps, you must pass in null as the first parameter.
Your form input names were all over the place. Be consistent: <input name="name" value={this.state.name} onChange={this.handleChange} />. Using input ids is not required nor recommended. In this case, this.handleChange utilizes e.target.name and e.target.value to track inputs and their values.
Make sure all inputs have been filled out before allowing the user to submit.
Avoid using fat arrow functions within the render method, for example: onChange={ (e) => this.handleChange(e) } because they'll be duplicated during each component re-render. Sometimes they're not avoidable, but aim to minimize usage.
Check for edge cases (like when details is empty), otherwise, your app will crash when attempting to map an undefined or empty object.
Actions should return a payload (standard naming convention).
Working example: https://codesandbox.io/s/qqlyqwnm3j
containers/ProductForm.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { submitDetails } from "../actions/";
import { browserHistory } from "react-router";
class ProductForm extends Component {
state = {
name: "",
price: "",
manufacturer: "",
condition: "",
manufactureDate: "",
expirationDate: ""
};
handleChange = e => this.setState({ [e.target.name]: e.target.value });
handleSubmit = e => {
e.preventDefault();
const {
name,
price,
manufacturer,
condition,
manufactureDate,
expirationDate
} = this.state;
if (
!name ||
!price ||
!manufacturer ||
!condition ||
!manufactureDate ||
!expirationDate
)
return;
this.props.submitDetails({ ...this.state });
browserHistory.push("/details");
};
render = () => (
<div style={{ textAlign: "center" }} className="container">
<form
style={{ width: 400, margin: "0 auto" }}
onSubmit={this.handleSubmit}
>
<h1 style={{ textAlign: "center" }}>Enter Product Details</h1>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Name</label>
<input
type="text"
className="uk-input"
name="name"
placeholder="Name of product"
onChange={this.handleChange}
value={this.state.name}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Price</label>
<input
type="number"
className="uk-input"
name="price"
placeholder="Product price"
onChange={this.handleChange}
value={this.state.price}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Manufacturer</label>
<input
type="text"
className="uk-input"
name="manufacturer"
placeholder="Product manufacturer"
onChange={this.handleChange}
value={this.state.manufacturer}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Condition</label>
<select
name="condition"
className="uk-select"
value={this.state.condition}
onChange={this.handleChange}
>
<option>Choose...</option>
<option>New</option>
<option>Used</option>
</select>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group "
>
<label style={{ paddingLeft: 10 }}>Manufacture Date</label>
<input
type="date"
className="uk-input"
name="manufactureDate"
onChange={this.handleChange}
value={this.state.manufactureDate}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group "
>
<label style={{ paddingLeft: 10 }}>Expiration Date</label>
<input
type="date"
className="uk-input"
name="expirationDate"
onChange={this.handleChange}
value={this.state.text}
/>
</div>
<button type="submit" className="uk-button uk-button-primary">
Submit
</button>
</form>
</div>
);
}
export default connect(
null,
{ submitDetails }
)(ProductForm);
containers/ShowDetails.js
import map from "lodash/map";
import isEmpty from "lodash/isEmpty";
import React from "react";
import { connect } from "react-redux";
const ShowDetails = ({ details }) =>
isEmpty(details) ? (
<div style={{ textAlign: "center", marginTop: 20 }}>
<h3 style={{ color: "red" }}>No Products Found!</h3>
</div>
) : (
<div style={{ textAlign: "center" }}>
<h1>Product Details </h1>
<table style={{ marginBottom: 10 }} className="products">
<thead className="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Manufacturer</th>
<th scope="col">Condition</th>
<th scope="col">Manufacture Date</th>
<th scope="col">Expiration Date</th>
</tr>
</thead>
<tbody>
{map(
details,
(
{
name,
price,
manufacturer,
condition,
manufactureDate,
expirationDate
},
key
) => (
<tr key={key}>
<td>{name}</td>
<td>${price}</td>
<td>{manufacturer}</td>
<td>{condition}</td>
<td>{manufactureDate}</td>
<td>{expirationDate}</td>
</tr>
)
)}
</tbody>
</table>
</div>
);
export default connect(state => ({ details: state.product.details }))(
ShowDetails
);
reducers/index.js
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { ADD_PRODUCT } from "../types";
const productReducer = (state = { details: [] }, { type, payload }) => {
switch (type) {
case ADD_PRODUCT:
return {
...state,
details: [...state.details, payload]
};
default:
return state;
}
};
export default combineReducers({
product: productReducer,
routing
});
actions/index.js
import { ADD_PRODUCT } from "../types";
export const submitDetails = payload => ({
type: ADD_PRODUCT,
payload
});

Resources