如何解决在类组件之外调用时,React setState 不会更新状态
所以对于学校项目,我需要使用 javascript 和 React 设计一个网站。我有两个对象,一个类组件实验和一个类组件 AddUsers。实验类需要一些参数才能发布到我们的 API 并运行实验。其中之一是包含一些用户 ID 的列表。可以使用其他类 AddUsers 获得此列表。 这两个类都在它们的状态中存储一个名为 m_DataUsers 的列表,表示用户 ID 的列表。 虽然添加用户时一切正常,但在 AddUser 类中更改 Experiment 的状态时会出现问题。我使用此网站遵循了教程:https://www.codeproject.com/Tips/1215984/Update-State-of-a-Component-from-Another-in-React
基本上,我需要在 Experiment 类之外定义一个函数,它使用 setState() 更新状态,我使用了 updateDataUsers(dataUsers),然后将其绑定到实验类。如果我错了,请纠正我,但我认为绑定函数的位置无关紧要,所以我在实验的构造函数中定义状态后才绑定它。我导出这个 updateDataUsers 函数,所以我从 AddUser 类调用它。调用该函数时,我可以看到 AddUsers 类成功提交了他的用户 ID 数组(我登录了控制台)。但是调用setState()后,状态不变。
我上网查了一下,发现调用setState()后,状态不一定会在调用setState()后直接更新。这不是一个真正的问题,但是当发布到 API 时,m_DataUsers 数组仍然是空的,而且我的 API 中也收到了一个空列表。所以我认为由于某种原因,setState() 函数没有更新 Experiment 的状态。
这是我的 updateDataUsers 函数
export function updateDataUsers(dataUsers){
this.setState({
m_DataUsers: dataUsers,});
console.log(this)
}
这是我的实验课
export default class Experiment extends React.Component{
constructor(experimentName,datasetName,props) {
super(props);
this.state = {
m_Name: experimentName,m_DatasetName: datasetName,m_Loading: false,m_DataUsers: [],}
updateDataUsers = updateDataUsers.bind(this);
}
getName(){
return this.state.m_Name;
}
runExperiment(){
console.log("RUNNING EXPERIMENT: ",this.state.m_DataUsers);
axios.post("/api/workspace/run",{userName: store.getState().userName,experimentName: this.state.m_Name,ids: this.state.m_DataUsers,nrOfRecommendations: 5})
.then(response => {
if (response.data.isSuccessful === "True"){
console.log("EXPERIMENT SUCCESSFUL",response.data);
}
else{
console.log(response.data.info)
}
})
.catch(error => console.log(error))
}
delete(){
axios.post("/api/workspace/deleteexperiment",experimentName: this.state.m_Name})
.then(response => {
if (response.data.isSuccessful === "True"){
console.log("deleted");
updateWorkspace();
}
else{
console.log(response.data.info)
}
})
}
render() {
return (
<RightBar>
<Box display="flex" alignContent="center">
<List style={{color: 'black'}}>
<ListItem>
<Typography variant="h6">
{this.state.m_Name}
</Typography>
</ListItem>
<Divider/>
<ListItem>
<Button variant="contained" onClick={() => this.runExperiment() }
style={{backgroundColor: colorScheme.primaryColor,color: 'white',top: 15,width: '10vw'}}>
run
</Button>
</ListItem>
<ListItem>
<Button variant="contained" onClick={() => this.delete() }
style={{backgroundColor: colorScheme.primaryColor,width: '10vw'}}>
delete
</Button>
</ListItem>
<ListItem>
<AddUsers experimentName={this.state.m_Name}/>
</ListItem>
</List>
</Box>
</RightBar>
)
}
}
最后,这是我的 AddUsers 类
export default class AddUsers extends React.Component{
constructor(props) {
super(props);
this.state = {
m_ExperimentName: props.experimentName,m_SelectedDataUsers: [],m_GotDataUsers: false,m_IsOpen: false,}
}
getDataUsers(){
axios.post("/api/workspace/getdatasetusers",experimentName: this.state.m_ExperimentName})
.then(response => {
if (response.data.isSuccessful === "True"){
let tempList = []
for (let i = 0; i < response.data.models[0].dataUsers.length; i++){
tempList.push({index: i,dataUserID: response.data.models[0].dataUsers[i].dataUserID.toString()})
}
this.setState({m_DataUsers: tempList,m_GotDataUsers: true})
}
else{
console.log(response.data.info);
}})
.catch(err => console.log(err))
}
dialogSwitch(){
if (this.state.m_IsOpen === true){
this.setState({m_IsOpen: false});
}
else{
this.setState({m_IsOpen: true});
}
}
pickUsers(){
const handleChange = (event) => {
if (event.target.checked === true){
let id = parseInt(event.target.name)
let tempList = this.state.m_SelectedDataUsers;
tempList.push(id);
this.setState({m_SelectedDataUsers: tempList});
}
else{
let id = parseInt(event.target.name);
let tempList = this.state.m_SelectedDataUsers;
let index = tempList.indexOf(id);
tempList.splice(index,1);
this.setState({m_SelectedDataUsers: tempList});
}
}
return (
<div className={{display: 'flex'}}>
<FormControl component="fieldset">
<Formlabel component="legend">
pick users
</Formlabel>
<FormGroup>
{
this.state.m_DataUsers.map(user =>{
return (
<FormControlLabel
control={<CheckBox onChange={handleChange} name={user.dataUserID}/>}
label={user.dataUserID}
/>
)
})
}
</FormGroup>
</FormControl>
</div>
)
}
isIDPicked(id,selected){
var found = false;
for (let j = 0; j < selected.length; j++) {
if (selected[j] === id) {
found = true;
break;
}
}
if (found === false){
return false;
}
else {
return true;
}
}
pickRandomUsers(){
var randomNr = Math.floor(Math.random() * (this.state.m_DataUsers.length)) + 1;
let selected = []
for (let i = 0; i < randomNr; i++){
var randomIndex = Math.floor(Math.random() * (this.state.m_DataUsers.length));
var id = this.state.m_DataUsers[randomIndex].dataUserID;
while (this.isIDPicked(id,selected) === true){
randomIndex = Math.floor(Math.random() * (this.state.m_DataUsers.length));
id = this.state.m_DataUsers[randomIndex].dataUserID;
}
selected.push(id);
}
this.setState({m_SelectedDataUsers: selected});
}
render() {
if (this.state.m_GotDataUsers === false){
this.getDataUsers();
}
return (
<div>
<Button
variant="contained"
style={{backgroundColor: colorScheme.primaryColor,width: '10vw'}}
onClick={() => this.dialogSwitch()}
>
add users
</Button>
<Dialog open={this.state.m_IsOpen}>
<DialogContent>
<Typography variant="h6">
Add users to experiment
</Typography>
</DialogContent>
<DialogContent>
<Button onClick={() => this.pickRandomUsers()}>
random
</Button>
</DialogContent>
<DialogContent>
{
this.pickUsers()
}
</DialogContent>
<DialogContent>
<Button onClick={() => this.dialogSwitch()}>
cancel
</Button>
<Button onClick={() => {
this.dialogSwitch();
updateDataUsers(this.state.m_SelectedDataUsers);
}}>
ok
</Button>
</DialogContent>
</Dialog>
</div>
)
}
}
提前致谢
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。