来自 bootstrap 表单的多 select - React Hooks
Multi-select from bootstrap form - React Hooks
我有一个产品列表,我希望用户能够从列表中选择一个或多个。
如果我 click/select 第一次使用产品,console.log
会显示正确的结果。
但是,如果我单击两次或更多次,则会出现错误:
TypeError: Cannot read property 'value' of null
我尝试了两种不同的策略,但都失败了(检查函数 addSelectedProducts
):
第一个解决方案
function SearchProductForm() {
const [selectedProducts, setSelectedProducts] = React.useState([]);
function handleSubmit(event){
event.preventDefault();
}
function addSelectedProducts(event) {
console.log(event.target.value)
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
return (
<div>
<Form>
<Form.Group controlId="exampleForm.ControlSelect2">
<Form.Label>Select the product(s) you are interested about:</Form.Label>
<Form.Control as="select" multiple onChange={(event) => addSelectedProducts(event)}>
<option value="product1">product1</option>
<option value="product2">product2</option>
<option value="product3">product3</option>
<option value="product4">product4</option>
<option value="product5">product5</option>
</Form.Control>
</Form.Group>
<Button variant="primary" type="submit" onClick={()=>handleSubmit()}>
Submit
</Button>
</Form>
</div>
);
}
export default SearchProductForm;
第二种解法
function SearchProductForm() {
const [selectedProducts, setSelectedProducts] = React.useState([]);
function handleSubmit(event){
event.preventDefault();
}
function addSelectedProducts(event) {
let options = event.target.options
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
}
}
return (
<div>
<Form>
<Form.Group controlId="exampleForm.ControlSelect2">
<Form.Label>Select the product(s) you are interested about:</Form.Label>
<Form.Control as="select" onChange={(event) => addSelectedProducts(event)} multiple>
<option value="product1">product1</option>
<option value="product2">product2</option>
<option value="product3">product3</option>
<option value="product4">product4</option>
<option value="product5">product5</option>
</Form.Control>
</Form.Group>
<Button variant="primary" type="submit" onClick={()=>handleSubmit()}>
Search
</Button>
</Form>
</div>
);
}
我想你可以试试 onChange={addSelectedProducts}
而不是 onChange={(event) => addSelectedProducts(event)}
嗨,你检查过 docs 了吗?也许你必须添加 event.persist()
因为你正在处理 function
.
中的 event
function addSelectedProducts(event) {
event.persist()
console.log(event.target.value)
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
其他解决方案可能涉及将变量设置为 event.target.value
:
function addSelectedProducts(event) {
let value = event.target.value;
console.log(event.target.value)
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
Ricardo 在他们的回答中提到了事件池,但我想提出一个不需要持久化事件的解决方案,这对我来说有点代码味。
您可以一次获取所有选定的选项,然后进行设置,而不是尝试将新状态与旧状态合并。
function addSelectedProducts(event) {
// Alternative if you need to target ie
// const selectedOptions = [...event.target.options].filter(o => o.selected).map(o => o.value)
const selectedOptions = [...event.target.selectedOptions].map(o => o.value)
setSelectedProducts(selectedOptions)
}
您遇到上述错误的原因是
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
是异步的,当调用回调时,您的活动已不存在。在此处查看更多信息:https://reactjs.org/docs/events.html#event-pooling
我有一个产品列表,我希望用户能够从列表中选择一个或多个。
如果我 click/select 第一次使用产品,console.log
会显示正确的结果。
但是,如果我单击两次或更多次,则会出现错误:
TypeError: Cannot read property 'value' of null
我尝试了两种不同的策略,但都失败了(检查函数 addSelectedProducts
):
第一个解决方案
function SearchProductForm() {
const [selectedProducts, setSelectedProducts] = React.useState([]);
function handleSubmit(event){
event.preventDefault();
}
function addSelectedProducts(event) {
console.log(event.target.value)
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
return (
<div>
<Form>
<Form.Group controlId="exampleForm.ControlSelect2">
<Form.Label>Select the product(s) you are interested about:</Form.Label>
<Form.Control as="select" multiple onChange={(event) => addSelectedProducts(event)}>
<option value="product1">product1</option>
<option value="product2">product2</option>
<option value="product3">product3</option>
<option value="product4">product4</option>
<option value="product5">product5</option>
</Form.Control>
</Form.Group>
<Button variant="primary" type="submit" onClick={()=>handleSubmit()}>
Submit
</Button>
</Form>
</div>
);
}
export default SearchProductForm;
第二种解法
function SearchProductForm() {
const [selectedProducts, setSelectedProducts] = React.useState([]);
function handleSubmit(event){
event.preventDefault();
}
function addSelectedProducts(event) {
let options = event.target.options
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
}
}
return (
<div>
<Form>
<Form.Group controlId="exampleForm.ControlSelect2">
<Form.Label>Select the product(s) you are interested about:</Form.Label>
<Form.Control as="select" onChange={(event) => addSelectedProducts(event)} multiple>
<option value="product1">product1</option>
<option value="product2">product2</option>
<option value="product3">product3</option>
<option value="product4">product4</option>
<option value="product5">product5</option>
</Form.Control>
</Form.Group>
<Button variant="primary" type="submit" onClick={()=>handleSubmit()}>
Search
</Button>
</Form>
</div>
);
}
我想你可以试试 onChange={addSelectedProducts}
而不是 onChange={(event) => addSelectedProducts(event)}
嗨,你检查过 docs 了吗?也许你必须添加 event.persist()
因为你正在处理 function
.
event
function addSelectedProducts(event) {
event.persist()
console.log(event.target.value)
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
其他解决方案可能涉及将变量设置为 event.target.value
:
function addSelectedProducts(event) {
let value = event.target.value;
console.log(event.target.value)
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
console.log(selectedProducts)
}
Ricardo 在他们的回答中提到了事件池,但我想提出一个不需要持久化事件的解决方案,这对我来说有点代码味。
您可以一次获取所有选定的选项,然后进行设置,而不是尝试将新状态与旧状态合并。
function addSelectedProducts(event) {
// Alternative if you need to target ie
// const selectedOptions = [...event.target.options].filter(o => o.selected).map(o => o.value)
const selectedOptions = [...event.target.selectedOptions].map(o => o.value)
setSelectedProducts(selectedOptions)
}
您遇到上述错误的原因是
setSelectedProducts(oldArray => [...oldArray, event.target.value]);
是异步的,当调用回调时,您的活动已不存在。在此处查看更多信息:https://reactjs.org/docs/events.html#event-pooling