#javascript #arrays #reactjs #react-state
Вопрос:
Поэтому для школьного проекта мне нужно создать веб-сайт с использованием javascript и реагировать. У меня есть два объекта, эксперимент с компонентами класса и надстройщики компонентов класса. Классу эксперимента потребуется несколько параметров, прежде чем он сможет опубликовать их в нашем API и запустить эксперимент. Одной из таких вещей является список, содержащий несколько идентификаторов пользователя. Этот список можно получить с помощью других пользователей классов. Оба класса хранят список под названием m_DataUsers в своем состоянии, представляющем список идентификаторов пользователей. В то время как все работает идеально при добавлении пользователей, проблема возникает при изменении состояния эксперимента в классе AddUser. Я следовал учебнику, используя этот сайт: https://www.codeproject.com/Tips/1215984/Update-State-of-a-Component-from-Another-in-React
В принципе, мне нужно определить функцию вне класса эксперимента, которая обновляет состояние с помощью setState (), я использовал updateDataUsers(источники данных), а затем привязал ее к классу эксперимента. Поправьте меня, если я ошибаюсь, но я не думаю, что имеет значение, где я привязываю функцию, поэтому я привязываю ее сразу после определения состояния в конструкторе эксперимента. Я экспортирую эту функцию updateDataUsers, поэтому вызываю ее из класса AddUser. При вызове функции я вижу, что класс AddUsers успешно отправил свой массив идентификаторов пользователя (я вошел в консоль). Но после вызова setState () состояние остается неизменным.
Я поискал в Интернете и обнаружил, что после вызова setState () состояние не обязательно будет обновляться непосредственно после вызова setState(). На самом деле это не проблема, но при отправке в API массив m_DataUsers по-прежнему пуст, и я также получаю пустой список в своем API. Поэтому я думаю, что по какой-то причине функция setState() не обновляет состояние эксперимента.
Вот моя функция 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", {userName: store.getState().userName, 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, color: 'white', top: 15, width: '10vw'}}>
delete
</Button>
</ListItem>
<ListItem>
<AddUsers experimentName={this.state.m_Name}/>
</ListItem>
</List>
</Box>
</RightBar>
)
}
}
And at last, here is my AddUsers class
export default class AddUsers extends React.Component{
constructor(props) {
super(props);
this.state = {
m_ExperimentName: props.experimentName,
m_DataUsers: [],
m_SelectedDataUsers: [],
m_GotDataUsers: false,
m_IsOpen: false,
}
}
getDataUsers(){
axios.post("/api/workspace/getdatasetusers", {userName: store.getState().userName, 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, color: 'white', top: 15, 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>
)
}
}
Thanks in advance