首页 > 解决方案 > React 函数在 Map 函数内的 if 条件中输入两次

问题描述

我的函数 handleAddPoint 接收这样的数据:

data = {colorid,counter}

我从名为“Qualificatif”的子组件中调用此函数,该子组件仅根据来自 Select 输入的 onChange 事件推送数据。

每次我从我的选择输入中更改值时,名为 handleAddPoint 的函数内的映射函数在 if 条件下执行两次。

你能帮助我吗 ?

这是代码:

export default class Questionnaire extends Component {
    constructor(props){
        super(props)

        this.state ={
            colors:[
                {
                    id:1,
                    color:"yellow",
                    point:0
                },
                {
                    id:2,
                    color:"green",
                    point:0
                },
                {
                    id:3,
                    color:"red",
                    point:0
                },
                {
                    id:4,
                    color:"blue",
                    point:0
                },
            ],
        }

        this.handleAddPoint = this.handleAddPoint.bind(this)
    }

    handleAddPoint = (data) =>{
        console.log("Data questionnaire",data)
        this.setState(state => {
            state.colors.map(color => 
                {if(color.id === data.colorid)
                    color.point += data.counter
                    return color
                })
        })
        console.log("couleurs questionnaire",this.state.colors)
    }

    render() {
        return (
            <div className="questionnaire">
                <Qualificatif data={Q1data} handleaddpoint={this.handleAddPoint}/>
                <Qualificatif data={Q2data} handleaddpoint={this.handleAddPoint}/>
                <Classement data={Q3data} handleaddpoint={this.handleAddPoint}/>
                <Result data={this.state.colors}/>
            </div>
        )
    }
}

标签: reactjsfunctiondictionaryif-statementstate

解决方案


我发现代码有问题的两件事是您在 handleAddPoint 中改变了状态,并且您尝试在 setState 之后记录状态,但 setState 不会立即更改状态,因此您不会记​​录更改后的状态。

这是一个工作示例,我猜其他组件也有一些破坏性问题,但由于它们没有发布在您的问题中,我只是从头开始创建它们。

const { Component } = React;
const Item = React.memo(function Component({
  data,
  handleaddpoint,
}) {
  return (
    <button onClick={() => handleaddpoint(data)}>
      add {data.color}
    </button>
  );
});
const Result = React.memo(function Result({ data }) {
  return <pre>{JSON.stringify(data, undefined, 2)}</pre>;
});
class Questionnaire extends Component {
  constructor(props) {
    super(props);

    this.state = {
      colors: [
        {
          id: 1,
          color: 'yellow',
          point: 0,
        },
        {
          id: 2,
          color: 'green',
          point: 0,
        },
        {
          id: 3,
          color: 'red',
          point: 0,
        },
        {
          id: 4,
          color: 'blue',
          point: 0,
        },
      ],
    };
    //handleAddPoint is an arrow function no need to bind
    //  it as arrow functions are automatically bound
    // this.handleAddPoint = this.handleAddPoint.bind(this);
  }

  handleAddPoint = (data) =>
    this.setState((state) => ({
      //you were mutating state.colors[x], you cannot
      //  mutate state
      colors: state.colors.map((color) =>
        color.id === data.id
          ? { ...color, point: color.point + 1 }
          : color
      ),
    }));

  render() {
    return (
      <div className="questionnaire">
        <Item
          data={this.state.colors[0]}
          handleaddpoint={this.handleAddPoint}
        />
        <Item
          data={this.state.colors[1]}
          handleaddpoint={this.handleAddPoint}
        />
        <Item
          data={this.state.colors[2]}
          handleaddpoint={this.handleAddPoint}
        />
        <Result data={this.state.colors} />
      </div>
    );
  }
}

ReactDOM.render(
  <Questionnaire />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>


推荐阅读