我有一个下拉菜单,可以添加和删除选项,但是我的问题是下拉菜单仅在刷新页面后更新。我希望它在按下添加或删除按钮后自动反映新的添加或删除。我相信答案与onSubmit和deleteRole方法被调用后更新状态有关。我是新来的反应者,不胜感激。提前致谢。这也是我的代码,这是下拉菜单的链接:http://a85febb5.ngrok.io/roles
import React, { Component } from 'react';
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import InputGroup from 'react-bootstrap/InputGroup';
import FormControl from 'react-bootstrap/FormControl'
import axios from 'axios';
import Select from 'react-select';
// modal docs: https://react-bootstrap.github.io/components/modal/
class Rolesmodal extends Component {
constructor(props) {
super(props);
this.updateInput = this.updateInput.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.deleteRole = this.deleteRole.bind(this)
this.state = {
show: false,
role: '',
roles: [],
selectedOption: null,
id: null,
}
}
// opens and closes the modal on click of Edit Roles Button
handleClose = () => {
this.setState({ show: false})
}
handleShow = () => {
this.setState({ show: true})
}
// gets roles data from database
componentDidMount() {
axios.get('http://localhost:4000/roles')
.then(res => {
this.setState({ roles: res.data });
})
.catch(function (error) {
console.log(error);
})
}
// When a role is selected in the dropdown the id of that role is set in the state
handleChage = (selectedOption) => {
this.setState({ selectedOption });
this.setState({ id: selectedOption.id})
}
// creates an array of roles
rolesList() {
return this.state.roles.map(currentrole => ({
label: currentrole.role_title, value: currentrole.role_title, id: currentrole._id
}))
}
updateInput = (e) => {
this.setState({
role: e.target.value
})
}
Capitalize(str){
return str.charAt(0).toUpperCase() + str.slice(1);
}
onSubmit() {
const roleadd = {
role_title: this.Capitalize(this.state.role)
}
console.log(roleadd);
axios.post('http://localhost:4000/roles/add', roleadd)
.then(res => console.log(res.data));
this.setState({
role: '',
})
}
deleteRole(id) {
// remove deleted item from state
axios.delete('http://localhost:4000/roles/'+this.state.id)
.then(response => { console.log(response.data)})
this.setState({
roles: this.state.roles.filter(el => el.id !== id)
})
}
render() {
console.log(this.state.id)
const roles = this.rolesList()
console.log(roles)
console.log(this.state.roles)
return (
<>
<Button style={{marginLeft: '20px'}} variant="outline-success" onClick={this.handleShow}>
Edit Roles
</Button>
<Modal show={this.state.show} onHide={this.handleClose} animation={true}>
<Modal.Header closeButton>
<Modal.Title>Edit Roles</Modal.Title>
</Modal.Header>
<Modal.Body style={{height: '300px'}}>
<div style={{display: 'flex',justifyContent: 'center', marginBottom: '20px' }}>
<InputGroup className="mb-3">
<FormControl
role={this.state.role}
value={this.state.role}
onChange={this.updateInput}
style={{width: '400px'}}
placeholder="Add new role"
aria-label="Add new role"
aria-describedby="basic-addon2"
/>
<Button onClick={this.onSubmit} style={{marginLeft: '10px', width: '75px'}} variant="success">Add</Button>
</InputGroup>
</div>
<div style={{display: 'flex',justifyContent: 'center'}}>
<div style={{width: '400px'}}>
<Select onChange={this.handleChage} options={ roles } />
</div>
<Button onClick={this.deleteRole} style={{marginLeft: '10px'}} variant="danger">Delete</Button>
</div>
</Modal.Body>
<Modal.Footer>
<Button variant="outline-secondary" onClick={this.handleClose}>
Close
</Button>
<Button variant="outline-primary" onClick={this.handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
}
export default Rolesmodal;
onSubmit() {
const roleadd = {
role_title: this.Capitalize(this.state.role)
}
console.log(roleadd);
axios.post('http://localhost:4000/roles/add', roleadd)
.then(res => console.log(res.data));
this.setState({
role: '',
roles: [...roles, roleadd]
})
也更新角色数组以反映添加的角色
下拉组件获取值,但不呈现它。由于它将旧数据道具与作为对象引用的新数据道具进行浅层比较,因此始终返回true;为了解决您需要force反应以在每个父组件渲染上重新渲染您的组件;如果key change,React将重新安装该组件;一个简单的解决方案是将键添加到选择的组件中(理想情况下基于角色,因此仅在更改角色时才更改),但是如果您无法找出理想的键值,则可以基于随机值,例如:
<Select key={Math.floor(Math.random() * 99999) onChange={this.handleChage} options={ roles } />
此键肯定会在父级的每个渲染上更改,但我并不是最有效的方法;但是,对于像这样的简单用例,就可以了;