React Switch Input 在第一次单击时未触发 SetState [重复]

Posted

技术标签:

【中文标题】React Switch Input 在第一次单击时未触发 SetState [重复]【英文标题】:React Switch Input not triggering SetState on first Click [duplicate] 【发布时间】:2021-04-09 05:29:42 【问题描述】:

大家晚上好,

我正在尝试使用句柄数据实现对组件的开关输入,以使用 Chart.js 显示图表。我正在构建的图表是一个分散的图表,其中一些点带有“接受”标签,而其他点则带有“拒绝”标签。我的问题来自应该允许用户显示“接受”和“拒绝”点的开关。

我的组件如下:

import React,  Component  from 'react'
import  Scatter  from 'react-chartjs-2';
import  SimulationResults  from '../SimulationResults';
    
export default class ScatterHeightLength extends Component 
    constructor(props)
        super(props);
        this.state = 
            ScatterData : ,
            AcceptedSwitch : false,
        
    
    
    ScatterDataConstructor (data)
        const HeightvsLength = data.map( result =>  return  x : result.length, y : result.height )
        const ColorHeightvsLength = data.map(result => 
            return (result.Rejection === 'Accepted' ? "rgba(75,192,192,0.4)" : "rgba(255,131,192,0.4)")
        )
        return (ScatterData: 
            labels : 'Scatter',
            datasets : [
                
                    label : ["Accepted", "Rejected"],
                    lineTension: 0.1,
                    backgroundColor: ColorHeightvsLength,
                    borderColor: ColorHeightvsLength,
                    borderCapStyle: "butt",
                    borderDash: ColorHeightvsLength,
                    borderDashOffset: 0.0,
                    borderJoinStyle: "miter",
                    pointBorderColor: ColorHeightvsLength,
                    pointBackgroundColor: ColorHeightvsLength,
                    pointBorderWidth: 1,
                    pointHoverRadius: 5,
                    pointHoverBackgroundColor: ColorHeightvsLength,
                    pointHoverBorderColor: ColorHeightvsLength,
                    pointHoverBorderWidth: 2,
                    pointRadius: 3,
                    pointHitRadius: 10,
                    data: HeightvsLength,
                
            ]
        )
    
    componentDidMount() 
        this.setState(ScatterData: this.ScatterDataConstructor(this.props.data).ScatterData);
        console.log(this.state.AcceptedSwitch, this.state.RejectedSwitch)
    

    componentDidUpdate(prevProps) 
        if(this.props.data !== prevProps.data)
            this.setState(ScatterData: this.ScatterDataConstructor(this.props.data).ScatterData);
            console.log(this.state.AcceptedSwitch, this.state.RejectedSwitch)
        
      
    handleToggleAccepted = () =>
        this.setState( AcceptedSwitch: !this.state.AcceptedSwitch);
        console.log(this.state.AcceptedSwitch, this.state.RejectedSwitch)
        this.FilterChartData();   
    ;
    FilterChartData =() =>
        if (this.state.AcceptedSwitch && this.state.RejectedSwitch)
            return this.setState( ScatterData:  )
        
        else if (this.state.AcceptedSwitch)
            const data = this.props.data.slice()
            for(var i=0; i <data.length; i++) 
                if (data[i].Rejection === "Accepted")
                    data.splice(i,1);
                    i--;
                
            
            return this.setState( ScatterData: this.ScatterDataConstructor(data).ScatterData )
        
        else if (this.state.RejectedSwitch)
            const data = this.props.data.slice()
            for(var i=0; i <data.length; i++) 
                if (data[i].Rejection === "Rejected")
                    data.splice(i,1);
                    i--;
                
            
            return this.setState( ScatterData: this.ScatterDataConstructor(data).ScatterData )
        
        else 
            return this.setState( ScatterData: this.ScatterDataConstructor(this.props.data).ScatterData)
        
    

    render() 
        return(
            <div className = "row">
                <div className = "col-xl-12 h-50">
                    <div className="container-fluid">
                        <div className="card border-left-primary shadow mb-4 h-50">
                            <div className="card-header py-3">
                                <h6 className="m-0 font-weight-bold text-primary">Height Versus Length </h6>
                            </div>
                            <div className="card-body">
                                <Scatter
                                data = this.state.ScatterData
                                width=200
                                height=400
                                options= 
                                    maintainAspectRatio: false,
                                    legend : 
                                        display :true,
                                        position : 'right'
                                    ,
                                
                                />
                            </div>
                            <div className="custom-control custom-switch">
                                <input type="checkbox" className="custom-control-input" id="AcceptedSwitch" + this.props.keyforelement onClick=this.handleToggleAccepted/>
                                <label className="custom-control-label" htmlFor="AcceptedSwitch" + this.props.keyforelement>Toggle this switch element</label> 
                            </div>                          
                        </div> 
                    </div>
                </div>
            </div>
        )
    

我的问题出现在第一次单击切换按钮时,没有任何反应,状态没有改变(当我控制台记录状态时,它显示 this.state.AcceptedSwitch 仍然是假的)。但在第一次点击后,状态会更新并更改“AcceptedSwitch”。

有人可以告诉我我在这里缺少什么吗? 谢谢!

【问题讨论】:

【参考方案1】:

由于setState 操作是异步的,您需要在 setState 回调中调用 this.FilterChartData() 函数以确保状态是最新的。

我认为你应该替换这个:

handleToggleAccepted = () =>
  this.setState( AcceptedSwitch: !this.state.AcceptedSwitch);
  console.log(this.state.AcceptedSwitch, this.state.RejectedSwitch)
  this.FilterChartData();   
;

作者:

handleToggleAccepted = () =>
  this.setState((prevState) => (
    AcceptedSwitch: !prevState.AcceptedSwitch
  ), () => 
    this.FilterChartData();
  );
;

让我知道此修复是否有效!

【讨论】:

以上是关于React Switch Input 在第一次单击时未触发 SetState [重复]的主要内容,如果未能解决你的问题,请参考以下文章

组件样式问题

如何在 React 组件中使用 switch 语句?

React - 两个不同的 Switch

react获取input value值的二中方法

在 React 函数组件中编写 switch 语句以进行渲染的正确方法是啥?

react获取input value值的二中方法