React Bootstrap select 选项在更新列表时呈现并且不显示第一个可用选项
React Bootstrap select option renders and does not display first available option when list renewed
项目使用ReactBootstraphttps://react-bootstrap.github.io/
该应用程序从 api 接收存储桶列表。有两个 select 下拉菜单。这里的objective是同一个bucket不能在两个select中都被selected。因此,如果第一个 select 包含 "Red" 个存储桶 select,则第二个下拉列表的列表中不能包含 "Red"。
我已经实现了第二个列表的创建和状态的正确更新。但是,当第二个下拉列表重新呈现时,在某些情况下,它会显示错误的条目 selected.
步骤:
- 初始负载:
第一个列表[红、绿、蓝]。已选择:红色。
第二个列表[绿色,蓝色]。已选择:绿色
- 在第一个下拉列表中 select 绿色:
第二个列表[红色,蓝色]。但是 selected 选项是蓝色的。它应该是红色的,因为它是列表中第一个可用的。
我知道这可能是因为 Red 之前不在第二个下拉列表中。但这不重要吗?看到列表更新了,组件重新渲染了
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
import ToBucket from "./toBucket";
class Buckets extends Component {
constructor(props) {
super(props);
this.state = {
fromBucketList: [],
toBucketList: [],
selectedFromBucket: [],
selectedToBucket: [],
};
}
handleFromBucketChange = (event) => {
let nam = event.target.name;
let bucketId = event.target.value;
const selectedFromBucket = this.getBucketById(bucketId);
let rebuiltToBucketList = [...this.state.fromBucketList];
let selectedFromBucketIndex = rebuiltToBucketList.indexOf(
selectedFromBucket
);
rebuiltToBucketList.splice(selectedFromBucketIndex, 1);
this.setState({ toBucketList: rebuiltToBucketList });
this.setState({ [nam]: selectedFromBucket });
this.setState({ selectedToBucket: rebuiltToBucketList[0] });
};
handleToBucketChange = (event) => {
let nam = event.target.name;
let bucketId = event.target.value;
const selectedToBucket = this.getBucketById(bucketId);
this.setState({ [nam]: selectedToBucket });
};
componentDidMount() {
const buckets = [
{ id: 1, color: "red" },
{ id: 2, color: "green" },
{ id: 3, color: "blue" },
];
let initialToBucketList = [...buckets];
initialToBucketList.splice(0, 1);
this.setState({ fromBucketList: buckets });
this.setState({ toBucketList: initialToBucketList });
this.setState({ selectedFromBucket: buckets[0] });
this.setState({ selectedToBucket: initialToBucketList[0] });
}
getBucketById = (id) => {
let foundedBucket = this.state.fromBucketList.find(
(element) => element.id == id
);
return foundedBucket;
};
render() {
return (
<React.Fragment>
<Form noValidate validated={this.state.validated}>
<Form.Group controlId="SelectFromBucket">
<Form.Label>Select FROM bucket:</Form.Label>
<Form.Control
required
type="text"
as="select"
onChange={this.handleFromBucketChange}
name="selectedFromBucket"
>
{this.state.fromBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
<React.Fragment>
<ToBucket
handleToBucketChange={this.handleToBucketChange}
toBucketList={this.state.toBucketList}
/>
</React.Fragment>
<p>
From :{this.state.selectedFromBucket.color}
<br></br>
To :{this.state.selectedToBucket.color}
</p>
</Form>
</React.Fragment>
);
}
}
export default Buckets;
第二个下拉菜单:
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
class ToBucket extends Component {
render() {
return (
<React.Fragment>
<Form.Group controlId="SelectToBucket">
<Form.Label>Select TO bucket:</Form.Label>
<Form.Control
required
type="text"
as="select"
onChange={this.props.handleToBucketChange}
name="selectedToBucket"
>
{this.props.toBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
</React.Fragment>
);
}
}
export default ToBucket;
我希望答案不是此代码的解决方法或 hack,而是如果此方法不正确,则可以作为另一个方向的概念指南。
第二个下拉列表的 FormControl 可能不会更改其值,因为没有传递给它的值道具。
尝试将所选值作为 props 从第一个桶传递到第二个桶
我从不使用 react-bootstrap 但这段代码应该有效。
第一个组件
<ToBucket
value={this.state.selectedToBucket && this.state.selectedToBucket.id}
handleToBucketChange={this.handleToBucketChange}
toBucketList={this.state.toBucketList}
/>
第二个组件
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
class ToBucket extends Component {
render() {
return (
<React.Fragment>
<Form.Group controlId="SelectToBucket">
<Form.Label>Select TO bucket:</Form.Label>
<Form.Control
required
value={this.props.value}
type="text"
as="select"
onChange={this.props.handleToBucketChange}
name="selectedToBucket"
>
{this.props.toBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
</React.Fragment>
);
}
}
export default ToBucket;
项目使用ReactBootstraphttps://react-bootstrap.github.io/
该应用程序从 api 接收存储桶列表。有两个 select 下拉菜单。这里的objective是同一个bucket不能在两个select中都被selected。因此,如果第一个 select 包含 "Red" 个存储桶 select,则第二个下拉列表的列表中不能包含 "Red"。
我已经实现了第二个列表的创建和状态的正确更新。但是,当第二个下拉列表重新呈现时,在某些情况下,它会显示错误的条目 selected.
步骤:
- 初始负载:
第一个列表[红、绿、蓝]。已选择:红色。 第二个列表[绿色,蓝色]。已选择:绿色
- 在第一个下拉列表中 select 绿色:
第二个列表[红色,蓝色]。但是 selected 选项是蓝色的。它应该是红色的,因为它是列表中第一个可用的。
我知道这可能是因为 Red 之前不在第二个下拉列表中。但这不重要吗?看到列表更新了,组件重新渲染了
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
import ToBucket from "./toBucket";
class Buckets extends Component {
constructor(props) {
super(props);
this.state = {
fromBucketList: [],
toBucketList: [],
selectedFromBucket: [],
selectedToBucket: [],
};
}
handleFromBucketChange = (event) => {
let nam = event.target.name;
let bucketId = event.target.value;
const selectedFromBucket = this.getBucketById(bucketId);
let rebuiltToBucketList = [...this.state.fromBucketList];
let selectedFromBucketIndex = rebuiltToBucketList.indexOf(
selectedFromBucket
);
rebuiltToBucketList.splice(selectedFromBucketIndex, 1);
this.setState({ toBucketList: rebuiltToBucketList });
this.setState({ [nam]: selectedFromBucket });
this.setState({ selectedToBucket: rebuiltToBucketList[0] });
};
handleToBucketChange = (event) => {
let nam = event.target.name;
let bucketId = event.target.value;
const selectedToBucket = this.getBucketById(bucketId);
this.setState({ [nam]: selectedToBucket });
};
componentDidMount() {
const buckets = [
{ id: 1, color: "red" },
{ id: 2, color: "green" },
{ id: 3, color: "blue" },
];
let initialToBucketList = [...buckets];
initialToBucketList.splice(0, 1);
this.setState({ fromBucketList: buckets });
this.setState({ toBucketList: initialToBucketList });
this.setState({ selectedFromBucket: buckets[0] });
this.setState({ selectedToBucket: initialToBucketList[0] });
}
getBucketById = (id) => {
let foundedBucket = this.state.fromBucketList.find(
(element) => element.id == id
);
return foundedBucket;
};
render() {
return (
<React.Fragment>
<Form noValidate validated={this.state.validated}>
<Form.Group controlId="SelectFromBucket">
<Form.Label>Select FROM bucket:</Form.Label>
<Form.Control
required
type="text"
as="select"
onChange={this.handleFromBucketChange}
name="selectedFromBucket"
>
{this.state.fromBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
<React.Fragment>
<ToBucket
handleToBucketChange={this.handleToBucketChange}
toBucketList={this.state.toBucketList}
/>
</React.Fragment>
<p>
From :{this.state.selectedFromBucket.color}
<br></br>
To :{this.state.selectedToBucket.color}
</p>
</Form>
</React.Fragment>
);
}
}
export default Buckets;
第二个下拉菜单:
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
class ToBucket extends Component {
render() {
return (
<React.Fragment>
<Form.Group controlId="SelectToBucket">
<Form.Label>Select TO bucket:</Form.Label>
<Form.Control
required
type="text"
as="select"
onChange={this.props.handleToBucketChange}
name="selectedToBucket"
>
{this.props.toBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
</React.Fragment>
);
}
}
export default ToBucket;
我希望答案不是此代码的解决方法或 hack,而是如果此方法不正确,则可以作为另一个方向的概念指南。
第二个下拉列表的 FormControl 可能不会更改其值,因为没有传递给它的值道具。
尝试将所选值作为 props 从第一个桶传递到第二个桶
我从不使用 react-bootstrap 但这段代码应该有效。
第一个组件
<ToBucket
value={this.state.selectedToBucket && this.state.selectedToBucket.id}
handleToBucketChange={this.handleToBucketChange}
toBucketList={this.state.toBucketList}
/>
第二个组件
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
class ToBucket extends Component {
render() {
return (
<React.Fragment>
<Form.Group controlId="SelectToBucket">
<Form.Label>Select TO bucket:</Form.Label>
<Form.Control
required
value={this.props.value}
type="text"
as="select"
onChange={this.props.handleToBucketChange}
name="selectedToBucket"
>
{this.props.toBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
</React.Fragment>
);
}
}
export default ToBucket;