setState不会立即更新吗?

时间:2020-07-29 22:36:36

标签: javascript reactjs create-react-app setstate

我有一个修改按钮,该按钮根据状态属性“ modalVisible”的值显示模式组件,换句话说,修改按钮触发事件处理程序,该事件处理程序更新状态属性,但是由于setState是异步的,因此无法正确显示(有时有时无法显示)

是否有其他方法可以在react中单击“修改”按钮后立即显示模态?

这是我的代码,我有4个组件:

第一个是 Todo组件,用于显示其他两个组件: DisplayTasks组件(待办事项列表)和 DisplayCompletedTasks (任务已完成)

第四个是模块组件(只是用于更改任务名称的输入文本),单击按钮“修改”按钮时会显示

第一个组件文件TaskManagements.js

import React from 'react'
import {DisplayTasks} from './DisplayTasks' 
import DisplayCompletedTasks from './DisplayCompletedTasks'

export class Todo extends React.Component{
  constructor(props){
    super(props);
    
    this.state={
        task: '',
        tasks: [],
        completedTasks: [],
        inputVisible: false,
        completedVisible: false,
        modalVisible: false,
        buttonClicked: '' 
    };
  }
  toggleInputDisplay = ()=>{
    this.setState(state=>({inputVisible: !state.inputVisible}));
  }
  handleChange = (event)=>{
    // Handle input checkboxes that handle completed tasks (the alternative is to use event.target.type==="checkboxes")
    if(event.target.name==="choosed"){
      //document.querySelector("input[value='" + event.target.value + "']").style.background-color = ""
      let arr = this.state.tasks;
      arr[event.target.value].checked = !arr[event.target.value].checked;
      this.setState({tasks: arr});
    } 
    // Handle the text input storing the text within the task state property 
    else if(event.target.type==="text"){
      this.setState({task: event.target.value});
    }
  }
  addTask = (event)=>{
    const arr = this.state.tasks;
    arr.push({task: this.state.task, checked: false});
    this.setState(state=>({tasks: arr, task: ''}));
  }
  removeTask = (event)=>{
    const arr = this.state.tasks;
    arr.splice(event.target.id,1);
    this.setState(state=>({tasks: arr}));
  }
  modifyTask = (event)=>{
    this.setState({modalVisible: true});
  }
  handleParam = (event)=>{
    const name = event.target.name;
    let arr = this.state.tasks;
    arr.forEach(task=>(task.checked = false));
    this.setState(state=>({completedVisible: !state.completedVisible, buttonClicked: name, 
      tasks: arr}));
    console.log(this.state.tasks);
  }
  handleChoosedTasks = (event)=>{
    //const inputVar = document.querySelectorAll("[value][name='completed']:checked");
    this.setState(state=>({tasks: state.tasks.filter(task=>(!task.checked)), completedVisible: false}));
    if(this.state.buttonClicked === 'complete'){
      const completedTasks = this.state.tasks.filter(task=>(task.checked));
      this.setState(state=>({completedTasks: state.completedTasks.concat(completedTasks)}));
      console.log('completed:' + this.state.completedTasks);
    }
  }
  render(){
      console.log(this.state.tasks);
      return(
        <div className="h-100">
            <button className="mt-4 btn btn-outline-primary" onClick={this.toggleInputDisplay}>Add Task</button>
            <div className="mt-5 ">{!this.state.inputVisible ? '' : (
              <div className="mb-4">
                <input className="mr-1"type="text" value={this.state.task} onChange={this.handleChange}/>
                <button className="btn btn-outline-secondary mr-1" onClick={this.addTask}>Add</button>
                <button className="btn btn-outline-secondary" onClick={this.toggleInputDisplay}>Cancel</button>
              </div>
                )      
              }
              <div className="row p-0 col-6 mx-auto ">
                <span style={{"paddingLeft": "14%"}} className=" mb-0 ml-0 col-10 ">Tasks</span>
              <button id="complete" name="complete" style={{"fontSize": "14px"}} className="btn btn-success col p-0" onClick={this.handleParam}>
                complete</button>
              <button id="remove" name="remove" style={{"fontSize": "14px","marginLeft":"5px"}} className="btn btn-danger col p-0" onClick={this.handleParam}>
                remove</button>
              </div>
              <DisplayTasks tasks={this.state.tasks} removeTask={this.removeTask} 
              completedVisible={this.state.completedVisible} handleChange={this.handleChange} 
              handleChoosedTasks={this.handleChoosedTasks} modifyTask={this.modifyTask} modalVisible={this.state.modalVisible}/>
              <span className=" mb-0 ">Completed</span>
              <DisplayCompletedTasks completedTasks={this.state.completedTasks}/>
            </div>
            
        </div>
      );
  }
}

第二个文件DisplayTasks.js

import React from 'react'
import ModifiedModal from './ModifiedModal.js'
import './DisplayTasks.css'

export class DisplayTasks extends React.Component{
  
  render(){
    return(
      <div id="tasks" style={{"height": "40vh"}} className="mt-2 mb-5 col-6 border border-primary mx-auto ">
        {!this.props.modalVisible? '' : <ModifiedModal />}
      <div style={{"height": "87%"}} className=" col-12 overflow-auto">{!this.props.tasks.length ? '' : this.props.tasks.map((task,index)=>
      (
        <div key={`task-${index}`} className="mt-3 mr-0 d-flex p-0 w-100 border">
          <div id="parent-task" style={!task.checked ? {...this.style}: {...this.style,"backgroundColor":"yellow"}} className="col-12  ml-0 p-0 d-flex">{!this.props.completedVisible ? '' 
          : (<label id="c-customized" className="border">
             <input name="choosed" type="checkbox" value={index}
             onChange={this.props.handleChange}/>
             <svg width="30" height="30">
               <g>
                 <circle className="c-b" cx="15" cy="15" r="14" stroke="magenta"/>
                 <polyline className="c-m" points="6,14 12,20 23,9"/>
               </g>
             </svg>
             </label>)}
          <strong className="ml-0 col-11 d-inline-block align-self-center">
            {task.task}
          </strong>
           
           <button id="modify-button" className="btn btn-primary btn-circle mr-1"><i value={index} className="fas fa-pencil-alt"
             onClick={this.props.modifyTask}></i></button>
          </div>
        </div>
        )
       )
      }
      </div>
      {!this.props.completedVisible ? '' 
      : <button id="choosed-confirmed" className="d-flex btn btn-success" onClick={this.props.handleChoosedTasks}>
        <span className="mx-auto align-self-center">Ok</span></button>}
      </div>
    )
  }
}

第四个是模态

import React from 'react'

export default function ModifiedModal(props){
  console.log("modifiedModal");
  return <div className="Modal d-flex ">
    <label>
      <button id="x-button"></button>
      <span>Modify the Task</span>
      <input type="text" />
    </label>
  </div>
}

1 个答案:

答案 0 :(得分:1)

使用setState的回调,如:

this.setState({ variable : updatedValue }, () => {
   after update works here...
}
);