如何更新我的输入以确保它具有最新值
How can I update my input to make sure it has the latest value
我有一个名为 productsTable
的反应组件,用户可以在其中指定他们想要的商品数量,然后将其添加到购物车。我正在使用 input
字段让他们输入产品数量。我遇到的问题是,如果用户输入输入字段的值并单击每个产品的添加到购物车,setState 将具有的值是输入字段中输入的最后一个值,而不是具有单个输入字段值。发生这种情况的原因是我使用 setState
的方式,它在输入的 onChange
中更新。关于我能做些什么来解决这个问题的任何想法。我在想也许把 input
作为它自己的独立组件,这样每个 product
都可以获得它自己的 input
实例。代码在下面。
import { Table, Button } from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import { useEffect, useState } from 'react';
import { getAllProducts } from '../../redux/actions/productActions';
import { sortBy } from 'lodash';
import { toast } from 'react-toastify';
import { addToCart } from '../../redux/actions/shoppingCartActions';
const ProductsTable = ({ searchTerm }) => {
const userInfo = JSON.parse(localStorage.getItem('userInfo')) || {};
const dispatch = useDispatch();
const [input, setInput] = useState(0);
const cartId = useSelector((state) => state.cartStatus.cartInfo.cartId);
const handleAdd = (product, input) => {
const isBadInput = validateInput(input);
if (isBadInput) {
toast.error('Invalid product amount', {
position: toast.POSITION.TOP_CENTER,
autoClose: 1200,
});
return;
}
const myProduct = {
productAmount: input,
...product,
userId: userInfo.userId,
cartId: cartId,
};
dispatch(addToCart(myProduct));
toast.success('Product added successfuly', {
position: toast.POSITION.TOP_CENTER,
autoClose: 1500,
});
};
useEffect(() => {
dispatch(getAllProducts());
}, []);
const products = useSelector((state) => state.productReducer.products);
const sortedProducts = sortBy(products, ({ productName }) =>
productName.toLowerCase()
);
const validateInput = (inputValue) => {
let value = parseInt(inputValue, 10);
if (value < 0) {
return true;
} else {
value = value >= 0 ? value : 0;
setInput(value);
}
};
return (
<div className='col-9'>
<Table striped bordered hover>
<thead>
<tr>
<th>Product Name</th>
<th>Product Price</th>
<th>Seller</th>
<th>Amount In Stock</th>
<th>Amount To Purchase</th>
<th></th>
</tr>
</thead>
<tbody>
{sortedProducts.length > 0 &&
sortedProducts
.filter((product) => {
const { productName } = product;
if (searchTerm === '') {
return product;
}
if (productName.toLowerCase().includes(searchTerm)) {
return product;
}
})
.map((product) => {
return (
<tr key={product.id}>
<td>{product.productName}</td>
<td>{product.productPrice}</td>
<td>Seller </td>
<td>{product.productInStock}</td>
<td>
<input
type='number'
name='input'
step='1'
onChange={(event) => setInput(event.target.value)}
/>
</td>
<td>
<Button
onClick={() => handleAdd(product, input)}
variant='primary'
>
Add To Cart
</Button>
</td>
</tr>
);
})}
</tbody>
</Table>
</div>
);
};
export default ProductsTable;
对于那些 运行 遇到类似问题的人,我将 input
字段移到了它自己的组件中,并在 productsTable
组件中调用了它。这样每个产品都有一个单独的输入字段。本来感觉是可以的,但是自己试了之后证明了。
我有一个名为 productsTable
的反应组件,用户可以在其中指定他们想要的商品数量,然后将其添加到购物车。我正在使用 input
字段让他们输入产品数量。我遇到的问题是,如果用户输入输入字段的值并单击每个产品的添加到购物车,setState 将具有的值是输入字段中输入的最后一个值,而不是具有单个输入字段值。发生这种情况的原因是我使用 setState
的方式,它在输入的 onChange
中更新。关于我能做些什么来解决这个问题的任何想法。我在想也许把 input
作为它自己的独立组件,这样每个 product
都可以获得它自己的 input
实例。代码在下面。
import { Table, Button } from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import { useEffect, useState } from 'react';
import { getAllProducts } from '../../redux/actions/productActions';
import { sortBy } from 'lodash';
import { toast } from 'react-toastify';
import { addToCart } from '../../redux/actions/shoppingCartActions';
const ProductsTable = ({ searchTerm }) => {
const userInfo = JSON.parse(localStorage.getItem('userInfo')) || {};
const dispatch = useDispatch();
const [input, setInput] = useState(0);
const cartId = useSelector((state) => state.cartStatus.cartInfo.cartId);
const handleAdd = (product, input) => {
const isBadInput = validateInput(input);
if (isBadInput) {
toast.error('Invalid product amount', {
position: toast.POSITION.TOP_CENTER,
autoClose: 1200,
});
return;
}
const myProduct = {
productAmount: input,
...product,
userId: userInfo.userId,
cartId: cartId,
};
dispatch(addToCart(myProduct));
toast.success('Product added successfuly', {
position: toast.POSITION.TOP_CENTER,
autoClose: 1500,
});
};
useEffect(() => {
dispatch(getAllProducts());
}, []);
const products = useSelector((state) => state.productReducer.products);
const sortedProducts = sortBy(products, ({ productName }) =>
productName.toLowerCase()
);
const validateInput = (inputValue) => {
let value = parseInt(inputValue, 10);
if (value < 0) {
return true;
} else {
value = value >= 0 ? value : 0;
setInput(value);
}
};
return (
<div className='col-9'>
<Table striped bordered hover>
<thead>
<tr>
<th>Product Name</th>
<th>Product Price</th>
<th>Seller</th>
<th>Amount In Stock</th>
<th>Amount To Purchase</th>
<th></th>
</tr>
</thead>
<tbody>
{sortedProducts.length > 0 &&
sortedProducts
.filter((product) => {
const { productName } = product;
if (searchTerm === '') {
return product;
}
if (productName.toLowerCase().includes(searchTerm)) {
return product;
}
})
.map((product) => {
return (
<tr key={product.id}>
<td>{product.productName}</td>
<td>{product.productPrice}</td>
<td>Seller </td>
<td>{product.productInStock}</td>
<td>
<input
type='number'
name='input'
step='1'
onChange={(event) => setInput(event.target.value)}
/>
</td>
<td>
<Button
onClick={() => handleAdd(product, input)}
variant='primary'
>
Add To Cart
</Button>
</td>
</tr>
);
})}
</tbody>
</Table>
</div>
);
};
export default ProductsTable;
对于那些 运行 遇到类似问题的人,我将 input
字段移到了它自己的组件中,并在 productsTable
组件中调用了它。这样每个产品都有一个单独的输入字段。本来感觉是可以的,但是自己试了之后证明了。