反应:更新特定元素的状态

时间:2019-09-12 12:56:41

标签: reactjs

我正在创建一个程序,用户应在其中键入正确的改组句子版本。就像下面的图片一样。

enter image description here

我想要的是,当用户有正确答案时,输入旁边会显示一个勾号。例如。

enter image description here

但是,不是针对所有输入,而是针对正确的输入。为了实现此功能,我使用状态,但是它没有给我期望的结果。如何确保特定行旁边显示一个勾号?

我的代码如下。

import React, { Component } from "react";
import { Button } from "react-bulma-components/full";
import { MdDoneAll } from "react-icons/md";
const uuidv1 = require("uuid/v1");


export default class DialogueShuffleFrame2 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      shuffledArray: [],
      inputAnswer: "",
      score:0,
      showTick:false
    };
    this.writeSomething = this.writeSomething.bind(this);
  }

  componentDidMount() {
    const shuffle = a => {
      var j, x, i;
      for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
      }
      return a;
    };

    let shuffledArray =
      this.props.lines[0].parts &&
      this.props.lines[0].parts.map(obj => {
        return {
          id: uuidv1(),
          parts: {
            speaker: obj.speaker,
            words: shuffle(obj.words.split(" "))
          },
          correctAnswer: obj.words
        };
      });

    this.setState({
      shuffledArray
    });
  }

  writeSomething(e) {
    e.preventDefault();
    this.setState({
      inputAnswer: e.target.value
    });
  }

  checkLines(str, obj) {
    obj.map(item => {
        //console.log(item.correctAnswer)
        if (item.correctAnswer === str.trim()) {

            //console.log('correct')
            this.setState({
                score:this.state.score + 80,
                inputAnswer:'',
                showTick:true
            })
        }
        return true
    })
  }

  render() {
    //console.log(this.state.shuffledArray);
    const shuffles =
      this.state.shuffledArray &&
      this.state.shuffledArray.map(item => (

        <li key={item.id}>
          <input onChange={this.writeSomething} />
          {this.state.showTick && <MdDoneAll style={{color:'blue'}}/>}
          <Button
              color="primary"
              onClick={() => {
                this.checkLines(this.state.inputAnswer, this.state.shuffledArray);
              }}
              size="small"
            >
              Check
            </Button>
          {item.parts.words.map((word, index) => (
            <span key={index}>{`${word} `}</span>
          ))}
        </li>
      ));
    return (
      <div>
        Dialogue 3<ul>{shuffles}</ul>
        {this.state.score}
      </div>
    );
  }
}

2 个答案:

答案 0 :(得分:2)

this.state.showTick在您的情况下是通用的。设置为true后,它将用于每个元素。 您需要将其更改为对象,然后使用item.id来显示刻度线。

第一:

 this.state = {
      shuffledArray: [],
      inputAnswer: "",
      score:0,
      showTick:{}
    };
checkLines(itemId, str, obj) {
    obj.map(item => {
        //console.log(item.correctAnswer)
        if (item.correctAnswer === str.trim()) {

            //console.log('correct')
            this.setState({
                score:this.state.score + 80,
                inputAnswer:'',
                showTick:{...this.state.showTick, itemId : true}
            })
        }
        return true
    })
  }
<li key={item.id}>
          <input onChange={this.writeSomething} />
          {this.state.showTick[item.id] && <MdDoneAll style={{color:'blue'}}/>}
          <Button
              color="primary"
              onClick={() => {
                this.checkLines(item.id, this.state.inputAnswer, this.state.shuffledArray);
              }}
              size="small"
            >
              Check
            </Button>
          {item.parts.words.map((word, index) => (
            <span key={index}>{`${word} `}</span>
          ))}
        </li>

让我知道它是否有效。如果没有整个代码,很难进行测试。

答案 1 :(得分:0)

首先,我在componentDidMount的生成对象showTick:false

中添加了属性showTick。
    const shuffle = a => {
      var j, x, i;
      for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
      }
      return a;
    };

    let shuffledArray =
      this.props.lines[0].parts &&
      this.props.lines[0].parts.map(obj => {
        return {
          id: uuidv1(),
          parts: {
            speaker: obj.speaker,
            words: shuffle(obj.words.split(" ")),
            showTick:false
          },
          correctAnswer: obj.words
        };
      });

    this.setState({
      shuffledArray
    });
  }

然后在checkLines函数中,我将showTick分配给true

checkLines(str, obj) {
    obj.map(item => {
        //console.log(item.correctAnswer)
        if (item.correctAnswer === str.trim()) {

            //console.log('correct')
            this.setState({
                score:this.state.score + 80,
                inputAnswer:''
            })
            item.parts.showTick = true
        }
        return true
    })
  }

然后在渲染部分中显示了它。

render() {
    //console.log(this.state.shuffledArray);
    const shuffles =
      this.state.shuffledArray &&
      this.state.shuffledArray.map(item => (

        <li key={item.id}>
          {item.parts.speaker}
          <input onChange={this.writeSomething} />
          {item.parts.showTick && <MdDoneAll style={{color:'blue'}}/>}
          <Button
              color="primary"
              onClick={() => {
                this.checkLines(this.state.inputAnswer, this.state.shuffledArray);
              }}
              size="small"
            >
              Check
            </Button>
          {item.parts.words.map((word, index) => (
            <span key={index}>{`${word} `}</span>
          ))}
        </li>
      ));
    return (
      <div>
        Dialogue 3<ul>{shuffles}</ul>
        {this.state.score}
      </div>
    );
  }