在我的项目中,我希望当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;
为帮助您理解,我将发布图片。 这是我最初得到的 这就是索引增加时得到的。 我也需要在第二张图片中加上下划线。这些下划线位于数组中,要获得下一个下划线,我需要将索引递增,但不是。
答案 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();
}
};