I want to convert React Class to Function (React Hooks) - javascript

I'm React Beginner.I trying to convert my React code written using class into function or React Hooks. Here is my code
import React, { Component, useState } from "react";
import { Badge, Card, Col, ListGroup, Row } from "react-bootstrap";
import { numberWithCommas } from "../utils/utils";
import Keranjang from "./Keranjang";
import TotalBayar from "./TotalBayar";
import { API_URL } from "../utils/constants";
import axios from "axios";
import swal from "sweetalert";
export default function Hasil(props) {
const [showModal, setShowModal] = useState(false);
const [keranjangDetail, setKeranjangDetail] = useState(false);
const [jumlah, setJumlah] = useState(0);
const [keterangan, setKeterangan] = useState("");
const [totalHarga, setTotalHarga] = useState(0);
const handleShow = (menuKeranjang) => {
setShowModal(true);
setKeranjangDetail(menuKeranjang);
setJumlah(menuKeranjang.jumlah);
setKeterangan(menuKeranjang.keterangan);
setTotalHarga(menuKeranjang.total_harga);
};
const handleClose = () => {
setShowModal(false);
};
const tambah = () => {
setJumlah(jumlah + 1);
setTotalHarga(keranjangDetail.product.harga * (jumlah + 1));
};
const kurang = () => {
if (jumlah !== 1) {
setJumlah(jumlah - 1),
setTotalHarga(keranjangDetail.product.harga * (jumlah - 1));
}
};
const changeHandler = (event) => {
setKeterangan(event.target.value);
};
const handleSubmit = (event) => {
event.preventDefault();
handleClose();
const data = {
jumlah: jumlah,
total_harga: totalHarga,
product: keranjangDetail.product,
keterangan: keterangan,
};
axios
.put(API_URL + "keranjangs/" + keranjangDetail.id, data)
.then((res) => {
swal({
title: "Update Pesanan!",
text: "Sukses Update Pesanan " + data.product.nama,
icon: "success",
button: false,
timer: 1500,
});
})
.catch((error) => {
console.log("Error yaa ", error);
});
};
const hapusPesanan = (id) => {
handleClose();
axios
.delete(API_URL + "keranjangs/" + id)
.then((res) => {
swal({
title: "Hapus Pesanan!",
text: "Sukses Hapus Pesanan " + keranjangDetail.product.nama,
icon: "error",
button: false,
timer: 1500,
});
})
.catch((error) => {
console.log("Error yaa ", error);
});
};
const { keranjangs } = useState(props);
return (
<Col md={3} className="mt-3">
<h4>
<strong>Keranjang</strong>
</h4>
<hr />
{keranjangs.length !== 0 && (
<Card className="overflow-auto hasil ">
<ListGroup variant="flush">
<Row className="category-aktif">
<Col xs={2} className="ml-3 mt-2">
<h5 className="ml-2">Jml</h5>
</Col>
<Col>
<h5 className="mt-2">Produk</h5>
</Col>
<Col>
<strong className="float-right mr-3 mt-2">Total Harga</strong>
</Col>
</Row>
{keranjangs.map((menuKeranjang) => (
<ListGroup.Item
key={menuKeranjang.id}
onClick={() => handleShow(menuKeranjang)}
>
<Row>
<Col xs={2}>
<h4>
<Badge pill variant="primary">
{menuKeranjang.jumlah}
</Badge>
</h4>
</Col>
<Col>
<h5>{menuKeranjang.product.nama}</h5>
<p>Rp. {numberWithCommas(menuKeranjang.product.harga)}</p>
</Col>
<Col>
<strong className="float-right">
Rp. {numberWithCommas(menuKeranjang.total_harga)}
</strong>
</Col>
</Row>
</ListGroup.Item>
))}
<Keranjang
handleClose={handleClose}
{...this.state}
tambah={tambah}
kurang={kurang}
changeHandler={changeHandler}
handleSubmit={handleSubmit}
hapusPesanan={hapusPesanan}
/>
</ListGroup>
</Card>
)}
<TotalBayar keranjangs={keranjangs} {...this.props} />
</Col>
);
}
but it give error said ./src/components/Hasil.js Line 68:7: Expected an assignment or function call and instead saw an expression no-unused-expressions
But I don't know what to do, anyone can help me? thanks in advance
btw, here is my original class code before convert it into function https://pastebin.com/0vTJ81kJ

I think the actual issue is a few lines up from what is being blamed.
There's an extraneous comma after setJumlah(jumlah - 1)
const kurang = () => {
if (jumlah !== 1) {
setJumlah(jumlah - 1), // <-- trailing comma at end of line
setTotalHarga(keranjangDetail.product.harga * (jumlah - 1));
}
};
It should be
const kurang = () => {
if (jumlah !== 1) {
setJumlah(jumlah - 1);
setTotalHarga(keranjangDetail.product.harga * (jumlah - 1));
}
};

this.state line should be removed or replaced in a functional way:
<Keranjang
handleClose={handleClose}
**{...this.state}** This is not for functional components
tambah={tambah}
kurang={kurang}
changeHandler={changeHandler}
handleSubmit={handleSubmit}
hapusPesanan={hapusPesanan}
/>
And also is extrange to have a coma here
const kurang = () => {
if (jumlah !== 1) {
setJumlah(jumlah - 1),// why coma
setTotalHarga(keranjangDetail.product.harga * (jumlah - 1));
}
};

Related

Why reducer function is running twice?

When I click Place Order button in placeOrderScreen.js placeOrderHandler runs which dispatches createOrder. According to logic createOrder should be dispatched just once when I click Place Order button but here createOrder is being dispatched twice which I am compeletly unable to understand.
First createorder dispatches before useEffect(which is normal) and then it dispatches after useEffect.
Before useEffect runs
After useEffect runs
I just want to run it once when I click Place Order button.
placeOrderScreen.js
import React, { useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import {
Button,
Row,
Col,
ListGroup,
Image,
Card,
ListGroupItem,
} from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import Message from '../components/Message';
import CheckoutSteps from '../components/CheckoutSteps';
import {
createOrder,
ORDER_CREATE_RESET,
} from '../features/OrderFeature/orderCreateSlice';
import { USER_DETAILS_RESET } from '../features/UserFeature/userDetailsSlice';
const PlaceOrderScreen = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const cart = useSelector((store) => store.cart);
//Calculate Prices
const addDecimals = (num) => {
return (Math.round(num * 100) / 100).toFixed(2);
};
//Cart object ko modify karny k leye local copy bnai hy ...kun k kuch additional chezein add karni thien(prices)
const cartObject = { ...cart };
cartObject.itemsPrice = addDecimals(
cartObject.cartItems.reduce((acc, item) => acc + item.price * item.qty, 0)
);
cartObject.shippingPrice = addDecimals(cartObject.itemsPrice < 100 ? 0 : 100);
cartObject.taxPrice = addDecimals(
Number((0.15 * cartObject.itemsPrice).toFixed(2))
);
cartObject.totalPrice = (
Number(cartObject.itemsPrice) +
Number(cartObject.shippingPrice) +
Number(cartObject.taxPrice)
).toFixed(2);
const orderCreate = useSelector((store) => store.orderCreate);
const { order, success, error } = orderCreate;
useEffect(() => {
// agr sab kuch theek sy chal gya hy (orderSlice mein) aur data mil gya hy to...
if (success) {
// agr order data mila hy to usmein sy _id property nikalo
navigate(`/order/${order._id}`);
dispatch(ORDER_CREATE_RESET());
dispatch(USER_DETAILS_RESET());
}
// To remove order._id dependency warning
// eslint-disable-next-line
}, [navigate, success]);
const placeOrderHandler = () => {
dispatch(
createOrder({
orderItems: cart.cartItems,
shippingAddress: cart.shippingAddress,
paymentMethod: cart.paymentMethod,
itemsPrice: cartObject.itemsPrice, //taken from new object which was copy of cart object
shippingPrice: cartObject.shippingPrice,
taxPrice: cartObject.taxPrice,
totalPrice: cartObject.totalPrice,
})
);
};
return (
<>
<CheckoutSteps step1 step2 step3 step4 />
<Row>
<Col md={8}>
<ListGroup variant='flush'>
<ListGroup.Item>
<h2>Shipping</h2>
<p>
<strong>Address:</strong>
{cart.shippingAddress.address},{cart.shippingAddress.city},
{cart.shippingAddress.postalCode},{cart.shippingAddress.country}
,
</p>
</ListGroup.Item>
<ListGroup.Item>
<h2>Payment Method</h2>
<strong>Method:</strong>
{cart.paymentMethod}
</ListGroup.Item>
<ListGroup.Item>
<h2>Order Items</h2>
{cart.cartItems.length === 0 ? (
<Message>Your Cart is empty</Message>
) : (
<ListGroup variant='flush'>
{cart.cartItems.map((item, index) => {
return (
<ListGroupItem key={index}>
<Row>
<Col md={1}>
<Image
src={item.image}
alt={item.name}
fluid
rounded
/>
</Col>
<Col>
<Link to={`/product/${item.product}`}>
{item.name}
</Link>
</Col>
<Col md={4}>
{item.qty} x ${item.price}=${item.qty * item.price}
</Col>
</Row>
</ListGroupItem>
);
})}
</ListGroup>
)}
</ListGroup.Item>
</ListGroup>
</Col>
<Col md={4}>
<Card>
<ListGroup variant='flush'>
<ListGroup.Item>
<h2>Order Summary</h2>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Items</Col>
<Col>${cartObject.itemsPrice}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Shipping</Col>
<Col>${cartObject.shippingPrice}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Tax</Col>
<Col>${cartObject.taxPrice}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Total</Col>
<Col>${cartObject.totalPrice}</Col>
</Row>
</ListGroup.Item>
<ListGroupItem>
{error && <Message variant='danger'>{error}</Message>}
</ListGroupItem>
<ListGroup.Item>
<Button
type='button'
className='btn-block'
disabled={cart.cartItems === 0}
onClick={placeOrderHandler}
>
Place Order
</Button>
</ListGroup.Item>
</ListGroup>
</Card>
</Col>
</Row>
</>
);
};
export default PlaceOrderScreen;
orderCreateSlice.js
import { createSlice, createAsyncThunk } from '#reduxjs/toolkit';
import axios from 'axios';
const initialState = {};
export const createOrder = createAsyncThunk(
'createOrder',
async (order, thunkAPI) => {
try {
const {
//userLogin .getState() sy nikalo aur userInfo variable usy day do
userLogin: { userInfo },
} = thunkAPI.getState();
const config = {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.post(`/api/orders`, order, config);
return data;
} catch (error) {
const newError =
error.response && error.response.data.message
? error.response.data.message
: error.message;
//This will end up in rejected section as payload... just error return karny sy fulfilled action run hora tha
return thunkAPI.rejectWithValue(newError);
}
}
);
const orderCreateSlice = createSlice({
name: 'orderCreate',
initialState,
reducers: {
ORDER_CREATE_RESET: () => {
return {};
},
},
extraReducers: {
//extra reducers sirf async operations k leye hein ... normally reducer use hongay
[createOrder.pending]: (state) => {
return {
loading: true,
};
},
[createOrder.fulfilled]: (state, action) => {
return {
loading: false,
success: true,
order: action.payload,
};
},
[createOrder.rejected]: (state, action) => {
return {
loading: false,
error: action.payload,
};
},
},
});
export const { ORDER_CREATE_RESET } = orderCreateSlice.actions;
export default orderCreateSlice.reducer;
store.js
import { configureStore } from '#reduxjs/toolkit';
import productListReducer from './features/productListFeature/productListSlice';
import productDetailsReducer from './features/productListFeature/productDetailSlice';
import CartReducer from './features/addToCart/cartSlice';
import userLoginReducer from './features/UserFeature/loginUserSlice';
import userRegisterReducer from './features/UserFeature/registerUserSlice';
import userDetailsReducer from './features/UserFeature/userDetailsSlice';
import userUpdateProfileReducer from './features/UserFeature/updateProfileSlice';
import orderCreateReducer from './features/OrderFeature/orderCreateSlice';
import orderDetailsReducer from './features/OrderFeature/orderDetailsSlice';
// yahan hum local storage sy data ly rahy hein jo cartSlice mein store kea tha ... JSON.parse is leye run kea hy kun k stringify kea tha data cartSlice mein
const cartItemsFromStorage = localStorage.getItem('cartItems')
? JSON.parse(localStorage.getItem('cartItems'))
: [];
const userInfoFromStorage = localStorage.getItem('userInfo')
? JSON.parse(localStorage.getItem('userInfo'))
: null; //agr user info ni available to null return kar do
const shippingAddressFromStorage = localStorage.getItem('shippingAddress')
? JSON.parse(localStorage.getItem('shippingAddress'))
: {};
const initialState = {
cart: {
cartItems: cartItemsFromStorage,
shippingAddress: shippingAddressFromStorage,
},
userLogin: {
userInfo: userInfoFromStorage,
},
};
const store = configureStore({
reducer: {
productList: productListReducer,
productDetails: productDetailsReducer,
cart: CartReducer,
userLogin: userLoginReducer,
userRegister: userRegisterReducer,
userDetails: userDetailsReducer,
userUpdateProfile: userUpdateProfileReducer,
orderCreate: orderCreateReducer,
orderDetails: orderDetailsReducer,
},
preloadedState: initialState, //for local storage
});
export default store;

Getting Parsing error: Unexpected token, expected "," error while passing addToCart in dispatch with two parameters

I am getting error Parsing error: Unexpected token, expected "," at line 55 while dispatching addToCart action with two parameters. I am using redux toolkit. At line 27 this dispatch method is working properly. Please see the picture below. I am passing two parameters as an object.(redux toolkit syntax for passing parameters in async function)
Error at line 55
//CartScreen
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link, useParams, useLocation } from 'react-router-dom';
import {
Row,
Col,
ListGroup,
Image,
Form,
Button,
Card,
} from 'react-bootstrap';
import Message from '../components/Message';
import { addToCart } from '../features/addToCart/cartSlice';
const CartScreen = () => {
const { id } = useParams();
const location = useLocation();
const qty = location.search ? Number(location.search.split('=')[1]) : 1;
const dispatch = useDispatch();
const cart = useSelector((store) => store.cart);
const { cartItems } = cart;
console.log(cart);
useEffect(() => {
if (id) {
dispatch(addToCart({ id, qty }));
}
}, [dispatch, id, qty]);
return (
<Row>
<Col md={8}>
<h1>Shopping Cart</h1>
{cartItems.length === 0 ? (
<Message>
Your Cart is empty <Link to='/'>Go Back</Link>{' '}
</Message>
) : (
<ListGroup variant='flush'>
{cartItems.map((item) => {
<ListGroup.Item key={item.product}>
<Row>
<Col md={2}>
<Image src={item.image} alt={item.name} fluid rounded />
</Col>
<Col md={3}>
<Link to={`/product/${item.product}`}>{item.name} </Link>
</Col>
<Col md={2}>${item.price}</Col>
<Col md={2}>
<Form.Control
as='select'
value={qty}
onChange={(e) => dispatch(addToCart({item.product,e.target.value}))}
>
{
[...Array(item.countInStock).keys()].map((x) => (
<option key={x + 1} value={x + 1}>
{x + 1}
</option>
))
}
console.log(...Array(product.countInStock).keys())
</Form.Control>
</Col>
</Row>
</ListGroup.Item>;
})}
</ListGroup>
)}
</Col>
<Col md={2}></Col>
<Col md={2}></Col>
</Row>
);
};
export default CartScreen;
//CartSlice
import { createSlice, createAsyncThunk, current } from '#reduxjs/toolkit';
import axios from 'axios';
export const addToCart = createAsyncThunk(
'addToCart',
async ({ id, qty }, thunkAPI) => {
//getting id and qty from cartScreen
try {
const { data } = await axios(`/api/products/${id}`);
localStorage.setItem(
'cartItems',
JSON.stringify(thunkAPI.getState().cart.cartItems)
); //data ko local storage save rakhny k lye... isko humny json.stringify kea hy kun k local storage mein sirf string store kr sakty... yahan hum ny local storage mein store kea hy lekin isko fetch store mein jakar krein gay
const productData = {
product: data._id,
name: data.name,
image: data.image,
price: data.price,
countInStock: data.countInStock,
qty,
};
return productData;
} catch (error) {
console.log(error);
}
}
);
const initialState = {
cartItems: [],
};
const cartSlice = createSlice({
name: 'cartReducer',
initialState,
extraReducers: {
[addToCart.pending]: (state) => {
state.cartItems = [];
},
[addToCart.fulfilled]: (state, action) => {
const item = action.payload;
const existItem = state.cartItems.find(
(cartItem) => cartItem.product === item.product
);
if (existItem) {
return {
...state,
cartItems: state.cartItems.map((cartItem) => {
return cartItem.product === existItem.product ? item : cartItem;
}),
};
} else {
state.cartItems = [...state.cartItems, item];
}
},
[addToCart.rejected]: (state) => {
state.cartItems = 'Some error has occured';
},
},
});
export default cartSlice.reducer;

Sending only the updated/newly created records to API in react hooks

I'm trying to get the updated/newly created records and send it to the backend in "queryparam"
import React, { useState, useEffect } from "react";
//import { Container, Row, Col } from "reactstrap";
// import Box from "#mui/material/Box";
// import "bootstrap/dist/css/bootstrap.css";
// import "./index.css";
const Index = () => {
const [formValues, setFormValues] = useState([
{ orderno: 0, inputValue1: "", inputValue2: "", checked: false }
]);
const [isDisabled, setDisabled] = useState(false);
// const [inputVal1, setInputval1] = useState();
const [isChanged, setIsChanged] = useState([]);
const [error, setError] = useState(false);
const [orderNumber, setOrderNumber] = useState(1);
const addFormFields = () => {
// if (error) {
// setDisabled(false)
// }
// else {
// setDisabled(true)
// }
setFormValues((prevState) => [
...prevState,
{
orderno: orderNumber,
inputValue1: "",
inputValue2: "",
checked: false
}
]);
setOrderNumber((prev) => prev + 1);
};
const removeFormFields = (i) => {
let newFormValues = [...formValues];
newFormValues.splice(i, 1);
setFormValues(newFormValues);
setOrderNumber((prev) => prev - 1);
};
const onChangeFieldValue = (index, key, value) => {
setFormValues((prevState) => {
let copyState = [...prevState];
if (value?.length > 0) {
setError(false);
} else {
setError(true);
}
copyState[index][key] = value;
return copyState;
});
};
const saveFields = (e) => {
const queryparam = {
inputData: formValues
};
setIsChanged(queryparam);
setIsChanged((prevState, nextState) => {
let copyState = [];
if (prevState === nextState) {
copyState = [...prevState];
} else {
copyState = [...nextState];
}
return copyState;
});
console.log(isChanged, "lllllllll");
};
// useEffect(() => {
// saveFields()
// }, [isChanged])
return (
<>
{formValues.map((element, index) => (
<div className="form-inline" key={index}>
{/* <Container>
<Row>
<Col xs="12" sm="6"> */}
<label>{index + 1}</label>
<input
type="text"
value={element.inputVal1}
onChange={(e) =>
onChangeFieldValue(index, "inputValue1", e.target.value)
}
/>
<input
type="text"
value={element.inputVal2}
required
onChange={(e) =>
onChangeFieldValue(index, "inputValue2", e.target.value)
}
/>
{/* </Col>
<Col xs="12" sm="6">
<Box> */}
<button
className={`button ${error ? "add" : "btn-secondary"}`}
type="button"
disabled={error}
onClick={(e) => addFormFields(e)}
>
Add{console.log(isDisabled, "ooooooo", error)}
</button>
<button
type="button"
className="button remove"
onClick={() => removeFormFields(index)}
>
Remove
</button>
{/* </Box>
</Col>
</Row>
</Container> */}
</div>
))}
{/* <Row>
<Col sm="6" md={{ size: 4, offset: 2 }}>
<Box> */}
<button
type="button"
className="button save"
onClick={(e) => saveFields(e)}
>
Save
</button>
<button
type="button"
className="button remove"
//onClick={(e) => cancelFields(e)}
>
cancel
</button>
{/* </Box>
</Col>
</Row> */}
</>
);
};
export default Index;
https://codesandbox.io/s/black-fire-ixeir?file=/src/App.js:3662-3701
In the above link,
Step1 : when I add values for inputs "123" in input1 and "345" in input2.Then when I click on "Save" the values sent are {"input1":"123","input2":"345"}.
Step2: Again I try to add one row for inputs "456" in input1 and "678" in input2.Then when I click on save the values sent are {"input1":"456","input2":"678"}.
When I edit the existing row, for example the first row values and when I click on "Save" then only the first row value should be sent as the second row values hasn't changed.Also, If I add new rows then the newly added only should be sent if the existing row values aren't changed. Is there any way to send only the updated/newly created values to the backend using react hook
You could use a separate changes object to track changes by orderno property; saved during add/update/remove, and committed when submitting.
const [changes, setChanges] = useState({});
...
const addFormFields = () => {
const newItem = {
orderno: orderNumber,
inputValue1: "",
inputValue2: "",
checked: false,
type: "add"
};
setFormValues((values) => [...values, newItem]);
setChanges((changes) => ({
...changes,
[newItem.orderno]: newItem
}));
setOrderNumber((prev) => prev + 1);
};
const removeFormFields = (index) => {
const item = {
...formValues[index],
type: "remove"
};
setFormValues((values) => values.filter((el, i) => i !== index));
setChanges((changes) => ({
...changes,
[item.orderno]: item
}));
};
const onChangeFieldValue = (index, key, value) => {
const item = {
...formValues[index],
[key]: value,
type: "edit"
};
setFormValues((prevState) => {
if (value?.length > 0) {
setError(false);
const copyState = [...prevState];
copyState[index] = item;
return copyState;
} else {
setError(true);
return prevState;
}
});
setChanges((changes) => ({
...changes,
[item.orderno]: item
}));
};
const saveFields = (e) => {
const queryparam = {
inputData: Object.values(changes)
};
console.log("Changes to commit", queryparam);
setChanges({});
};

How to Receive the one stepper state value in to the another stepper in React js

I have created a stepper as a functional component as below
import NewProfile from './NewProfile';
function getSteps() {
return ['Carete Profile', 'Contact'];
}
function getStepContent(step) {
switch (step) {
case 0:
return <NewProfile type={valueTobePass}></NewProfile>;
default:
return <contact></contact>;
}
}
export default function HorizontalLinearStepper(props,previousState)
{
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [publisherId, setPublisherId] = React.useState(0);
const [skipped, setSkipped] = React.useState(new Set());
const steps = getSteps();
const isStepOptional = (step) => {
return (step === 1 ||
step === 2)
};
console.log(props.newUserId);
const isStepSkipped = (step) => {
return skipped.has(step);
};
const addPublisherid =(publisherId) => {
setPublisherId(publisherId);
console.log(publisherId)
}
const handleNext = () => {
let newSkipped = skipped;
if (isStepSkipped(activeStep)) {
newSkipped = new Set(newSkipped.values());
newSkipped.delete(activeStep);
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped(newSkipped);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped((prevSkipped) => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(activeStep);
return newSkipped;
});
}
return (
<div className={classes.root}>
<Stepper activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps = {};
const labelProps = {};
if (isStepOptional(index)) {
labelProps.optional = <Typography variant="caption">Optional</Typography>;
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={index} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
{props.step}
</Stepper>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
All steps completed - you&apos;re finished
</Typography>
</div>
) : (
<div>
<Typography className={classes.instructions}>{getStepContent(activeStep,previousState,props.type)}</Typography>
<div>
<Button disabled={activeStep === 0} onClick={handleBack} className={classes.button}>
Back
</Button>
{isStepOptional(activeStep) && (
<Button
variant="contained"
color="primary"
onClick={handleSkip}
className={classes.button}
>
Skip
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={handleNext}
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
)}
</div>
</div>
);
}
and the step is class component
class NewProfile extends Component {
constructor(props) {
super(props);
this.state = {
Name: '',
newUserId:'',
}
}
editAccountDetails = () => {
axios.post(`url`, {
"Name": this.state.Name,
})
.then(response => response.data)
.then((data) => {
this.setState({newUserId:data.id})
}).catch(error => { console.log(error); })
}
render() {
return <div>
<TextField }}
onChange={(event) => {
this.setState({ "Name":
event.target.value })
}} />
<Button onClick={this.editAccountDetails} >
Submit </MButton>
</div>
</div>
}
}
const NewProfileHOC = withStyles(styles)(NewProfile);
export default connect(mapStateToProps, mapDispatchToProps)(NewProfileHOC);
I want to retrieve the 'state' of the 'NewProfile' Component(Class Component) in the Stepper Component (Functional Component) for my further process
i tried with callBack function and context it is not working please help me out with this
thank you in advance

Checkbox isChecked doesn't affect the price

I've two different prices,
when i check the checkbox for second price,
the state show and display the second price properly
but when i press the pay button of that product with second price, it will send the first price
instead of what I've checked which was second price.
so i want increment both prices separately when i checked the check box and
it sends the specific price to the payment process
import React, { useState, useEffect } from "react";
import {
getProducts,
getBraintreeClientToken,
processPayment,
createOrder
} from "./apiCore";
import { emptyCart } from "./cartHelpers";
import { isAuthenticated } from "../auth";
import { Link } from "react-router-dom";
import "braintree-web";
import DropIn from "braintree-web-drop-in-react";
import { makeStyles } from '#material-ui/core/styles';
import TextField from '#material-ui/core/TextField';
const useStyles = makeStyles((theme) => ({
root: {
'& > *': {
margin: theme.spacing(1),
width: '25ch',
},
},
}));
const Checkout = ({ products, setRun = f => f, run = undefined }) => {
const classes = useStyles();
const [data, setData] = useState({
loading: false,
success: false,
clientToken: null,
error: "",
instance: {},
address: "",
mobile:""
});
>>>>>> const [price, setPrice]= useState(() => () => getTotal())
>>>>>> const [isChecked, setIsChecked]= useState(false);
const userId = isAuthenticated() && isAuthenticated().user._id;
const token = isAuthenticated() && isAuthenticated().token;
const getToken = (userId, token) => {
getBraintreeClientToken(userId, token).then(data => {
if (data.error) {
setData({ ...data, error: data.error });
} else {
setData({ clientToken: data.clientToken });
}
});
};
useEffect(() => {
getToken(userId, token);
}, []);
const handleAddress = event => {
setData({ ...data, address: event.target.value });
};
const handleMobile = event => {
setData({ ...data, mobile: event.target.value });
};
>>>>>> const getTotal = () => {
>>>>>> return products.reduce((currentValue, nextValue) => {
>>>>>> return currentValue + nextValue.count * nextValue.price;
>>>>>>
>>>>>> }, 0);
>>>>>> };
>>>>>> const getTotal2 = () => {
>>>>>> return products.reduce((currentValue, nextValue) => {
>>>>>> return currentValue + nextValue.count * nextValue.price2;
>>>>>> }, 0);
>>>>>> };**
const showCheckout = () => {
return isAuthenticated() ? (
<div>{showDropIn()}</div>
) : (
<Link to="/signin">
<button className="btn btn-primary">Sign in to checkout</button>
</Link>
);
};
let deliveryAddress = data.address
let deliveryMobile = data.mobile
const buy = () => {
setData({ loading: true });
// send the nonce to your server
// nonce = data.instance.requestPaymentMethod()
let nonce;
let getNonce = data.instance
.requestPaymentMethod()
.then(data => {
// console.log(data);
nonce = data.nonce;
// once you have nonce (card type, card number) send nonce as 'paymentMethodNonce'
// and also total to be charged
// console.log(
// "send nonce and total to process: ",
// nonce,
// getTotal(products)
// );
>>>>>> **const paymentData = {
>>>>>> paymentMethodNonce: nonce,
>>>>>> amount: getTotal(products)
>>>>>> };**
processPayment(userId, token, paymentData)
.then(response => {
console.log(response);
// empty cart
// create order
const createOrderData = {
products: products,
transaction_id: response.transaction.id,
amount: response.transaction.amount,
address: deliveryAddress,
mobile: deliveryMobile
};
createOrder(userId, token, createOrderData)
.then(response => {
emptyCart(() => {
setRun(!run); // run useEffect in parent Cart
console.log(
"payment success and empty cart"
);
setData({
loading: false,
success: true
});
});
})
.catch(error => {
console.log(error);
setData({ loading: false });
});
})
.catch(error => {
console.log(error);
setData({ loading: false });
});
})
.catch(error => {
// console.log("dropin error: ", error);
setData({ ...data, error: error.message });
});
};
const showDropIn = () => (
<div onBlur={() => setData({ ...data, error: "" })}>
{data.clientToken !== null && products.length > 0 ? (
<div>
<div className="gorm-group mb-3">
<label className="text-muted">Delivery address:</label>
<textarea
onChange={handleAddress}
className="form-control"
value={data.address}
placeholder="Type your delivery address here..."
/>
</div>
<div className="gorm-group mb-3">
<label className="text-muted">mobile number:</label>
<form className={classes.root} noValidate autoComplete="off">
<TextField placeholder="mobile number" onChange={handleMobile} type="text" value={data.mobile} id="outlined-basic" label="mobile" variant="outlined" />
</form>
</div>
<DropIn
options={{
authorization: data.clientToken,
paypal: {
flow: "vault"
}
}}
onInstance={instance => (data.instance = instance)}
/>
<button onClick={buy} className="btn btn-success btn-block">
Pay
</button>
</div>
) : null}
</div>
);
const showError = error => (
<div
className="alert alert-danger"
style={{ display: error ? "" : "none" }}
>
{error}
</div>
);
const showSuccess = success => (
<div
className="alert alert-info"
style={{ display: success ? "" : "none" }}
>
Thanks! Your payment was successful!
</div>
);
const showLoading = loading =>
loading && <h2 className="text-danger">Loading...</h2>;
return (
<div>
>>>>>> **<form>
>>>>>> <h1>قیمت کل: {isChecked ? getTotal2() : getTotal()} </h1>
>>>>>> <label>نیم لیتر :</label>
>>>>> <input type="checkbox"
>>>>>> checked={isChecked}
>>>>>> onChange={(e)=>{setIsChecked(e.target.checked)}}/>
>>>>>> </form>**
{showLoading(data.loading)}
{showSuccess(data.success)}
{showError(data.error)}
{showCheckout()}
</div>
);
};
export default Checkout;
my card component
import React, { useState, version,useEffect } from 'react';
import { Link, Redirect } from 'react-router-dom';
import ShowImage from './ShowImage';
import moment from 'moment';
import { addItem, updateItem, removeItem } from './cartHelpers';
import logo from '../images/logo.svg'
//material ui
import Card from '#material-ui/core/Card';
import CardContent from '#material-ui/core/CardContent';
import { makeStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import Grid from '#material-ui/core/Grid'
import { Typography } from '#material-ui/core';
import CardHeader from '#material-ui/core/CardHeader';
import CardMedia from '#material-ui/core/CardMedia';
import CardActions from '#material-ui/core/CardActions';
import Collapse from '#material-ui/core/Collapse';
import Avatar from '#material-ui/core/Avatar';
import IconButton from '#material-ui/core/IconButton';
import MoreVertIcon from '#material-ui/icons/MoreVert';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Menu from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
import { create } from 'jss';
import rtl from 'jss-rtl';
import { StylesProvider, jssPreset } from '#material-ui/core/styles';
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const useStyles = makeStyles((theme) => ({
stock: {
marginBottom: '1rem'
},
Button: {
...theme.typography.button,
padding: '.3rem',
minWidth: 10,
},
media: {
height: 0,
paddingTop: '56.25%', // 16:9
},
title: {
backgroundColor: '#D8D8D8'
},
grid: {
padding: '0'
},
cardFont:{
...theme.typography.body,
textAlign:'right',
marginTop:'.8rem',
marginRight:'1rem'
},productName:{
...theme.typography.body,
textAlign:'right',
},
cardButton:{
marginLeft:'1.4rem'
}
}));
const Cardd = ({
product,
showViewProductButton = true,
showAddToCartButton = true,
cartUpdate = false,
showRemoveProductButton = false,
setRun = f => f,
run = undefined
// changeCartSize
}) => {
const [redirect, setRedirect] = useState(false);
const [count, setCount] = useState(product.count);
//material ui
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
// console.log(price)
const classes = useStyles()
const showViewButton = showViewProductButton => {
return (
showViewProductButton && (
<Link to={`/product/${product._id}`} className="mr-2">
<Button className={classes.Button} size="small" variant="contained">مشاهده محصول</Button>
</Link>
)
);
};
const addToCart = () => {
// console.log('added');
addItem(product, setRedirect(true));
};
const shouldRedirect = redirect => {
if (redirect) {
return <Redirect to="/cart" />;
}
};
const showAddToCartBtn = showAddToCartButton => {
return (
showAddToCartButton && (
<Button className={classes.Button} size="small" onClick={addToCart} variant="contained" color="primary" disableElevation>
اضافه کردن به سبد
</Button>
)
);
};
const showStock = quantity => {
return quantity > 0 ? (
<Button disabled size="small" className={classes.stock}>موجود </Button>
) : (
<Button className={classes.stock}>ناموجود </Button>
);
};
const handleChange = productId => event => {
setRun(!run); // run useEffect in parent Cart
setCount(event.target.value < 1 ? 1 : event.target.value);
if (event.target.value >= 1) {
updateItem(productId, event.target.value);
}
};
const showCartUpdateOptions = cartUpdate => {
return (
cartUpdate && (
<div>
<div className="input-group mb-3">
<div className="input-group-prepend">
<span className="input-group-text">تعداد</span>
</div>
<input type="number" className="form-control" value={count} onChange={handleChange(product._id)} />
</div>
</div>
)
);
};
const showRemoveButton = showRemoveProductButton => {
return (
showRemoveProductButton && (
<Button className={classes.Button} size="small" variant="contained" color="secondary" disableElevation
onClick={() => {
removeItem(product._id);
setRun(!run); // run useEffect in parent Cart
}}
>
حذف محصول
</Button>
)
);
};
return (
<Grid container direction='column' >
<Grid item >
<Card style={{margin:'1rem'}}>
<Grid item className={classes.title}>
<Typography className={classes.productName} variant='h6'>
{product.name}
</Typography>
</Grid>
<CardHeader
avatar={
<Avatar alt="Remy Sharp" src={logo} className={classes.green}>
</Avatar>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title="روغنک"
subheader="September 14, 2016"
/>
<CardContent className={classes.grid} >
{shouldRedirect(redirect)}
<ShowImage item={product} url="product" />
<StylesProvider jss={jss}>
<Typography className={classes.cardFont} variant="body2" component="p">
{product.description.substring(0, 100)}
</Typography>
</StylesProvider>
<div>
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
<Typography className={classes.cardFont} variant="body2" component="p">
$یک لیتر {product.price}
</Typography>
<Typography className={classes.cardFont} variant="body2" component="p">
$نیم لیتر {product.price2}
</Typography>
<Typography className={classes.cardFont} variant="body2" component="p">
Category: {product.category && product.category.name}
</Typography>
<Typography className={classes.cardFont} variant="body2" component="p">
Added on {moment(product.createdAt).fromNow()}
</Typography>
<Typography className={classes.cardFont} variant="body2" component="p">
{showStock(product.quantity)}
</Typography>
<br />
<Grid container >
<Grid item className={classes.cardButton} >
{showViewButton(showViewProductButton)}
</Grid>
<Grid item className={classes.cardButton}>
{showAddToCartBtn(showAddToCartButton)}
</Grid>
<Grid item className={classes.cardButton}>
{showRemoveButton(showRemoveProductButton)}
</Grid>
</Grid>
{showCartUpdateOptions(cartUpdate)}
</CardContent>
</Card>
</Grid>
</Grid>
// <div className="card ">
// <div className="card-header card-header-1 ">{product.name}</div>
// <div className="card-body">
// {shouldRedirect(redirect)}
// <ShowImage item={product} url="product" />
// <p className="card-p mt-2">{product.description.substring(0, 100)} </p>
// <p className="card-p black-10">$ {product.price}</p>
// <p className="black-9">Category: {product.category && product.category.name}</p>
// <p className="black-8">Added on {moment(product.createdAt).fromNow()}</p>
// {showStock(product.quantity)}
// <br />
// {showViewButton(showViewProductButton)}
// {showAddToCartBtn(showAddToCartButton)}
// {showRemoveButton(showRemoveProductButton)}
// {showCartUpdateOptions(cartUpdate)}
// </div>
// </div>
);
};
export default Cardd;
CartHelper component
export const addItem = (item = [], count = 0, next = f => f) => {
let cart = [];
if (typeof window !== 'undefined') {
if (localStorage.getItem('cart')) {
cart = JSON.parse(localStorage.getItem('cart'));
}
cart.push({
...item,
count: 1
});
// remove duplicates
// build an Array from new Set and turn it back into array using Array.from
// so that later we can re-map it
// new set will only allow unique values in it
// so pass the ids of each object/product
// If the loop tries to add the same value again, it'll get ignored
// ...with the array of ids we got on when first map() was used
// run map() on it again and return the actual product from the cart
cart = Array.from(new Set(cart.map(p => p._id))).map(id => {
return cart.find(p => p._id === id);
});
localStorage.setItem('cart', JSON.stringify(cart));
next();
}
};
export const itemTotal = () => {
if (typeof window !== 'undefined') {
if (localStorage.getItem('cart')) {
return JSON.parse(localStorage.getItem('cart')).length;
}
}
return 0;
};
export const getCart = () => {
if (typeof window !== 'undefined') {
if (localStorage.getItem('cart')) {
return JSON.parse(localStorage.getItem('cart'));
}
}
return [];
};
export const updateItem = (productId, count) => {
let cart = [];
if (typeof window !== 'undefined') {
if (localStorage.getItem('cart')) {
cart = JSON.parse(localStorage.getItem('cart'));
}
cart.map((product, i) => {
if (product._id === productId) {
cart[i].count = count;
}
});
localStorage.setItem('cart', JSON.stringify(cart));
}
};
export const removeItem = productId => {
let cart = [];
if (typeof window !== 'undefined') {
if (localStorage.getItem('cart')) {
cart = JSON.parse(localStorage.getItem('cart'));
}
cart.map((product, i) => {
if (product._id === productId) {
cart.splice(i, 1);
}
});
localStorage.setItem('cart', JSON.stringify(cart));
}
return cart;
};
export const emptyCart = next => {
if (typeof window !== 'undefined') {
localStorage.removeItem('cart');
next();
}
};

Categories