反应:如何再次渲染状态,该状态在componentDidMount生命周期方法中已更改一次?

时间:2020-04-06 09:24:41

标签: reactjs

在我的项目中,我希望当nameGuessed: dashedName[this.state.index]的索引更改时重新渲染该部分

问题在于它是在componentDidMount中触发的,有没有办法更改此状态?

我的整个代码看起来像这样。

import React, { Component } from "react";
import correct from "../data/media/correct.wav";
import denied from "../data/media/denied.mp3";
import type from "../data/media/type.wav";

var _ = require("lodash");

class MatchTranscriptedWordToPicture extends Component {
  constructor(props) {
    super(props);

    this.state = {
      index: 0,
      nameGuessed: [],
      data: "",
      wordIndex: 0,
      disabled: false,
      nameIsCorrect: false,
    };
  }

  componentDidMount() {
    /* let splittedCompany = this.props.data[this.state.index].companyRus.trim();
        let splittedName = this.props.data[this.state.index].rusName.trim();
        let dashedName = splittedName.split("").map((item) => {
            let str = ''
            return str += ' _'  
        })
        console.log()
        let randomLetters = this.randomizeLetters(this.props.data[this.state.index].companyRus, this.props.data[this.state.index].rusName)
        this.setState({
            companyRus: splittedCompany, rusName: splittedName, randomLetters,nameGuessed:dashedName.join("")
        }); */
    let arr = [];
    let dashedName = [];

    this.props.data.map((item) => {
      let obj = {
        picture: item.picture,
        engName: item.engName,
        engCompany: item.companyEng,
        rusCompany: item.companyRus,
        rusName: item.rusName,
        scrambleLetters: this.randomizeLetters(item.companyRus, item.rusName),
        correctAnswer: item.rusName + ", " + item.companyRus,
        dashedWord: this.dashedWord(item.rusName, item.companyRus),
      };

      //console.log(item)
      //console.log(arr)
      //console.log(obj)
      return (
        arr.push(obj),
        dashedName.push(this.dashedWord(item.rusName, item.companyRus))
      );
    });

    this.setState({
      data: arr,
      nameGuessed: dashedName[this.state.index],
    });
  }

  dashedWord(str1, str2) {
    let str = str1 + ", " + str2;
    let composed = " ";
    str.split("").map((item) => (composed += "_ "));
    return composed.trim();
  }

  letterUnderlines(word) {
    return word;
  }

  handleGuess = (evt) => {
    let ltr = evt.target.value;
    let typing = new Audio(type);
    typing.play();
    console.log(ltr);

    this.setState(
      (prevState) => {
        const updatedState =
          prevState.nameGuessed.substring(0, this.state.wordIndex) +
          ltr +
          prevState.nameGuessed.substring(this.state.wordIndex + 2);
        return {
          nameGuessed: updatedState,
          wordIndex: this.state.wordIndex + 1,
        };
      },
      () => {
        if (this.state.wordIndex === this.state.nameGuessed.length) {
          this.setState({
            disabled: true,
          });
        }
      }
    );
  };

  removeLetters = () => {
    //console.log("clicked")
    let typing = new Audio(type);
    typing.play();
    this.setState(
      (prevState) => {
        let part1 = prevState.nameGuessed.substring(0, prevState.wordIndex - 1);
        let part2 = prevState.nameGuessed.substring(
          prevState.wordIndex,
          prevState.nameGuessed.length
        );
        let updatedState = part1 + " _" + part2;

        return {
          nameGuessed: updatedState,
          wordIndex: this.state.wordIndex - 1,
        };
      },
      () => {
        if (
          this.state.wordIndex !==
          this.state.nameGuessed[this.state.index].length
        ) {
          this.setState({
            disabled: false,
          });
        }
      }
    );
  };

  randomizeLetters(str1, str2) {
    let wordSplitted1 = str1.split("");
    let wordSplitted2 = str2.split("");
    let arr = [wordSplitted1, wordSplitted2, ","].flat();
    let shuffled = _.shuffle(arr);
    return shuffled;
  }

  checkAnswer = () => {
    if (
      this.state.nameGuessed ===
      this.state.data[this.state.index].correctAnswer.trim()
    ) {
      let audio = new Audio(correct);
      audio.play();
      this.setState({
        nameIsCorrect: true,
        index: this.state.index + 1,
        nameGuessed: [],
      });
    } else {
      let audio = new Audio(denied);
      audio.play();
    }
  };

  render() {
    //console.log(this.state.nameGuessed.length === this.state.wordIndex);
    //console.log(this.state.nameGuessed, this.state.rusName);
    console.log(this.state.nameGuessed);
    console.log(
      this.state.nameGuessed === this.state.data[this.state.index] &&
        this.state.data[this.state.index].correctAnswer.trim(),
      this.state.nameGuessed,
      this.state.data[this.state.index] &&
        this.state.data[this.state.index].correctAnswer.trim()
    );

    return (
      <div className="columns is-multiline is-vcentered">
        {this.props.data && (
          <div className="column is-3">
            <div className="card">
              <div className="card-image">
                <figure className="image is-4by3">
                  <img src={this.props.data[this.state.index].picture} alt="" />
                </figure>
              </div>
              <div className="card-content">
                <div className="media">
                  <div className="media-content">
                    <p className="title is-4">
                      {this.props.data[this.state.index].engName}
                    </p>
                    <p className="subtitle is-6">
                      {this.props.data[this.state.index].companyEng}
                    </p>
                  </div>
                </div>
              </div>
              <div className="card-content">
                <div className="media">
                  <div className="media-content">
                    <p className="title is-4">
                      {this.state.nameGuessed && this.state.nameGuessed}
                      <button
                        className="button is-small"
                        onClick={this.removeLetters}
                        disabled={this.state.wordIndex <= 0}
                      >
                        <span className="icon is-small">
                          <i className="fas fa-backspace"></i>
                        </span>
                      </button>
                    </p>
                    {this.state.disabled && (
                      <button
                        onClick={this.checkAnswer}
                        className={`button is-small ${
                          this.state.nameIsCorrect && "is-success"
                        }`}
                      >
                        <span class="icon is-small">
                          <i class="fas fa-check-circle"></i>
                        </span>
                      </button>
                    )}
                    <p className="subtitle is-6"></p>
                  </div>
                </div>
              </div>
              <div className="card-content">
                <div className="media">
                  <div className="media-content">
                    <div className="tags">
                      {this.state.data[this.state.index] &&
                        this.state.data[this.state.index].scrambleLetters.map(
                          (letter) => (
                            <button
                              disabled={this.state.disabled}
                              className="tag is-dark is-light is-medium"
                              value={letter}
                              onClick={this.handleGuess}
                              styles={{ cursor: "pointer" }}
                            >
                              {letter}
                            </button>
                          )
                        )}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }
}

export default MatchTranscriptedWordToPicture;

为帮助您理解,我将发布图片。 这是我最初得到的 enter image description here 这就是索引增加时得到的。 enter image description here 我也需要在第二张图片中加上下划线。这些下划线位于数组中,要获得下一个下划线,我需要将索引递增,但不是。

2 个答案:

答案 0 :(得分:0)

如果您不执行任何异步操作,则可以将所有代码放入render()函数中。您也不需要使用状态。这是您的修改后的代码:

import React, { Component } from 'react';
import correct from '../data/media/correct.wav';
import denied from '../data/media/denied.mp3';
import type from '../data/media/type.wav';


var _ = require('lodash');


class MatchTranscriptedWordToPicture extends Component {
    constructor (props) {
        super(props);

        this.state = {
            index: 0,
            nameGuessed: [],
            data: '',
            wordIndex: 0,
            disabled: false,
            nameIsCorrect: false
        };


    }

    dashedWord(str1, str2) {
        let str = str1 + ", " + str2;
        let composed = " ";
        str.split("").map((item) => composed += "_ ");
        return composed.trim();

    }

    letterUnderlines(word) {
        return word;
    }

    handleGuess = (evt) => {
        let ltr = evt.target.value;
        let typing = new Audio(type);
        typing.play();
        console.log(ltr);

        this.setState(prevState => {
            const updatedState = prevState.nameGuessed.substring(0, this.state.wordIndex) + ltr + prevState.nameGuessed.substring(this.state.wordIndex + 2);
            return ({
                nameGuessed: updatedState, wordIndex: this.state.wordIndex + 1
            });
        }, () => {
            if (this.state.wordIndex === this.state.nameGuessed.length) {
                this.setState({
                    disabled: true
                });
            }
        });

    };

    removeLetters = () => {
        //console.log("clicked")
        let typing = new Audio(type);
        typing.play();
        this.setState(prevState => {
            let part1 = prevState.nameGuessed.substring(0, prevState.wordIndex - 1);
            let part2 = prevState.nameGuessed.substring(prevState.wordIndex, prevState.nameGuessed.length);
            let updatedState = part1 + " _" + part2;

            return ({
                nameGuessed: updatedState, wordIndex: this.state.wordIndex - 1
            });
        }, () => {
            if (this.state.wordIndex !== this.state.nameGuessed[this.state.index].length) {
                this.setState({
                    disabled: false
                });
            }
        });




    };

    randomizeLetters(str1, str2) {
        let wordSplitted1 = str1.split('');
        let wordSplitted2 = str2.split('');
        let arr = [wordSplitted1, wordSplitted2, ","].flat();
        let shuffled = _.shuffle(arr);
        return shuffled;
    }

    checkAnswer = () => {
        if (this.state.nameGuessed === this.state.data[this.state.index].correctAnswer.trim()) {
            let audio = new Audio(correct);
            audio.play();
            this.setState({
                nameIsCorrect: true, index: this.state.index + 1, nameGuessed: []
            });

        } else {
            let audio = new Audio(denied);
            audio.play();
        }
    };

    render() {
        //console.log(this.state.nameGuessed.length === this.state.wordIndex);
        //console.log(this.state.nameGuessed, this.state.rusName);
        console.log(this.state.nameGuessed);
        console.log(this.state.nameGuessed === this.state.data[this.state.index] && this.state.data[this.state.index].correctAnswer.trim(), this.state.nameGuessed, this.state.data[this.state.index] && this.state.data[this.state.index].correctAnswer.trim());

       /* let splittedCompany = this.props.data[this.state.index].companyRus.trim();
        let splittedName = this.props.data[this.state.index].rusName.trim();
        let dashedName = splittedName.split("").map((item) => {
            let str = ''
            return str += ' _'  
        })
        console.log()
        let randomLetters = this.randomizeLetters(this.props.data[this.state.index].companyRus, this.props.data[this.state.index].rusName)
        this.setState({
            companyRus: splittedCompany, rusName: splittedName, randomLetters,nameGuessed:dashedName.join("")
        }); */
        let arr = [];
        let dashedName = [];

        this.props.data.map((item) => {
            let obj = {
                picture: item.picture,
                engName: item.engName,
                engCompany: item.companyEng,
                rusCompany: item.companyRus,
                rusName: item.rusName,
                scrambleLetters: this.randomizeLetters(item.companyRus, item.rusName),
                correctAnswer: item.rusName + ", " + item.companyRus,
                dashedWord: this.dashedWord(item.rusName, item.companyRus)
            };

            //console.log(item)
            //console.log(arr)
            //console.log(obj)
            return (arr.push(obj), dashedName.push(this.dashedWord(item.rusName, item.companyRus)));

        });

        this.setState({
            data: arr, nameGuessed: dashedName[this.state.index]
        });

        return (
            <div className="columns is-multiline is-vcentered">
                { this.props.data &&
                    <div className="column is-3">
                        <div className="card">
                            <div className="card-image">
                                <figure className="image is-4by3">
                                    <img src={ this.props.data[this.state.index].picture } alt="" />
                                </figure>
                            </div>
                            <div className="card-content">
                                <div className="media">
                                    <div className="media-content">
                                        <p className="title is-4">{ this.props.data[this.state.index].engName }</p>
                                        <p className="subtitle is-6">{ this.props.data[this.state.index].companyEng }</p>
                                    </div>
                                </div>
                            </div>
                            <div className="card-content">
                                <div className="media">
                                    <div className="media-content">
                                        <p className="title is-4">{ this.state.nameGuessed && this.state.nameGuessed }
                                            <button className="button is-small" onClick={ this.removeLetters } disabled={ this.state.wordIndex <= 0 }>
                                                <span className="icon is-small">
                                                    <i className="fas fa-backspace"></i>
                                                </span>
                                            </button>
                                        </p>
                                        { this.state.disabled && (<button onClick={ this.checkAnswer } className={ `button is-small ${this.state.nameIsCorrect && 'is-success'}` }>
                                            <span class="icon is-small">
                                                <i class="fas fa-check-circle"></i>
                                            </span>
                                        </button>) }
                                        <p className="subtitle is-6"></p>
                                    </div>
                                </div>
                            </div>
                            <div className="card-content">
                                <div className="media">
                                    <div className="media-content">
                                        <div className="tags">{ this.state.data[this.state.index] && this.state.data[this.state.index].scrambleLetters.map((letter) => (
                                            <button disabled={ this.state.disabled } className="tag is-dark is-light is-medium" value={ letter } onClick={ this.handleGuess } styles={ { cursor: 'pointer' } }>{ letter }</button>
                                        )) }</div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                }

            </div>
        );
    }
}

export default MatchTranscriptedWordToPicture;

答案 1 :(得分:0)

我通过添加以下代码找到了解决方案

update() {
        let dashedName = [];
        this.props.data.map((item) => {
            return ( dashedName.push(this.dashedWord(item.rusName, item.companyRus)));
        });
        this.setState({
            nameGuessed: dashedName[this.state.index+1],wordIndex:0, disabled:false
        });
}

进入

checkAnswer = () => {
        if (this.state.nameGuessed === this.state.data[this.state.index].correctAnswer.trim()) {
            let audio = new Audio(correct);
            audio.play();
            this.setState({
                nameIsCorrect: true, index: this.state.index + 1
            });
        this.update()
        } else {
            let audio = new Audio(denied);
            audio.play();
        }
    };