I have a problem with my Formik
and checkbox. I wanted to display the current value of the order which te checked values would determine. The problem is that when I tried to either call function sumProducts or addChecked inside Formik
there:
{(values) => {
sumProducts(values.values.checked)
it doesn’t work correctly. It seems like it multiplies the original price * 3.
Anyway I wouldn’t like to use sumProducts immedietaly, because at first I wanted to determine whether I unchecked or checked the checkbox. That’s why I created the addChecked
function, but when after checking if the value is being checked or unchecked and wanting to call the function sumProducts
inside addChecked I have error that I went into infinite loop/renders.
import { Formik,Field,Form,ErrorMessage } from 'formik';
import React, {useState} from 'react';
import {v4 as uuidv4 } from 'uuid';
import {connect} from "react-redux";
import {Order} from "../../ducks/orders/OrderInterfaces";
import {addOrder} from "../../ducks/orders/OrderActions";
import {RootStore} from "../../ducks/RootReducer";
import {Product} from "../../ducks/products/ProductsInterfaces";
import {User} from "../../ducks/users/UserInterfaces";
interface OrdersFormProps {
addOrder: (order: Order) => void,
products: Product[],
users: User[]
}
const ProductsForm = ({addOrder, products, users}: OrdersFormProps) => {
interface OrdersFormValues {
id: string,
client: string,
checked: Array<string>
}
const initialValues: OrdersFormValues = {
id: uuidv4(),
client: '',
checked: [],
}
const handleSubmit = (values: OrdersFormValues) => {
console.log(values)
// addOrder(values)
}
const [checked,setChecked] = useState<string[]>([])
const [currentPrice,setCurrentPrice] = useState(0)
const addChecked = (prod: string) => {
checked.find(product => product === prod) ? checked.filter(product => product !== prod)
: setChecked(prev => [...prev,prod])
//sumProducts(checked)
}
const sumProducts = (prod: Array<string>) => {
const sum = prod.reduce((acc,curr) => {
const currProduct = products.find(product => product.id === curr)
if (currProduct) {
return acc+currProduct.price
}
return acc
}, 0)
setCurrentPrice(currentPrice => currentPrice+sum)
}
return (
<div>
<Formik
initialValues={
initialValues
}
onSubmit={(values, {resetForm}) => {handleSubmit(values); resetForm({values: undefined})}}
enableReinitialize={true}>
{(values) => {
//sumProducts(values.values.checked)
return (
<Form>
<label htmlFor="client">Client:
<Field name="client" as="select">
<option disabled value="">(select a client)</option>
{users && users.map(user => (
<option value={user.id} key={user.id}>{user.firstName} {user.lastName}</option>
))}
</Field>
{products && products.map(product =>
<label>
<Field type="checkbox" name="checked" value={product.id} key={product.id} /> {product.name}
</label>
)}
</label>
<button type="submit">
Submit
</button>
</Form>
)}}
</Formik>
<p>Current price of order: {currentPrice}</p>
</div>
);
};
const mapStateToProps = (state: RootStore) => {
return {
products: state.products.products,
users: state.users.users
}
}
const mapDispatchToProps = {
addOrder
}
export default connect(mapStateToProps,mapDispatchToProps)(ProductsForm);