基于其他示例,我的正则表达式尝试用字母替换破折号(-)应该有效。但事实并非如此。我正在使用React。
我已经关注了该帖子(Replace multiple characters in one replace call)和其他外部帖子,但是我无法使用正则表达式来将破折号(-)替换为某些字母。该应用程序只有一个组件App.js。我也尝试过写行targetNameDashes.replace(/'-'/ gi,letter).toUpperCase();但它也不起作用。
GitHub存储库:https://github.com/irene-rojas/brooklyn-react
import React, { Component } from 'react';
import './App.css';
class App extends Component {
state = {
names: ['JAKE', 'AMY', 'GINA', 'ROSA', 'CHARLES', 'TERRY', 'HOLT'],
targetName: "",
targetNameDashes: "",
guessRemain: 10,
lettersGuessed: []
}
componentDidMount() {
let targetName = this.state.names[Math.floor(Math.random()*this.state.names.length)];
this.setState({
targetName: targetName,
targetNameDashes: targetName.replace(/[a-zA-Z]/gi , '-').toUpperCase(),
// The flags 'g' and 'i' are for global search and case insensitive search
});
console.log(targetName);
}
onKeyUp = (event) => {
event.preventDefault();
let letter = event.key.toUpperCase();
let targetName = this.state.targetName;
let guessRemain = this.state.guessRemain;
let lettersGuessed = this.state.lettersGuessed;
if (letter) {
this.setState({
guessRemain: guessRemain - 1,
lettersGuessed: lettersGuessed + letter
});
// if letter is in targetName, replace dash with letter
if (targetName.includes(letter)) {
console.log("yup");
let targetNameDashes = this.state.targetNameDashes;
// temporary variable that contains dashes and letters?
targetNameDashes.replace(/-/gi, letter).toUpperCase();
this.setState({
targetNameDashes: targetNameDashes
// does it need a callback to update?
});
}
}
if (guessRemain === 0) {
console.log("too bad");
this.setState({
guessRemain: 10,
lettersGuessed: []
});
this.componentDidMount();
}
console.log(`${letter} end of onKeyUp`);
}
render() {
return (
<div className="App">
<div>
You will be seen by:
<br></br>
{this.state.targetNameDashes}
</div>
<br></br>
<div>
Letters guessed:
<br></br>
<input onKeyUp={this.onKeyUp} />
<br></br>
Letters guessed in this round:
<br></br>
[ {this.state.lettersGuessed} ]
</div>
<br></br>
<div>
Guesses remaining:
<br></br>
{this.state.guessRemain}
</div>
</div>
);
}
}
export default App;
答案 0 :(得分:1)
我注意到许多问题,我应该一一提及:
names
。将它们设置为状态是没有意义的,因为它们不会在UI中更改和重新呈现。componentDidMount
,但这不是他们应该这样做的方式。在单独的实用程序函数中分离需要重新执行的逻辑(即gameReset()
并调用它)。 targetName.includes(letter)
不正确的情况下的替换逻辑。它不知道要替换哪些索引。
这样想:您问targetName
是“ EVE”
一个看起来像“ ---”的字符串,更改为“ E”所在的位置。怎么能
是否无需检查原始名称就知道“ E”在哪里?一个循环
会是一个更好的解决方案。
setState
本质上是异步的。您应该使用prevState
参数和回调方法来确保获得正确的状态。在这里,我修改了您的代码并在必要时添加了注释,希望对您有所帮助:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
// moved it outside state
const names = ["JAKE", "AMY", "GINA", "ROSA", "CHARLES", "TERRY", "HOLT"];
class App extends React.Component {
state = {
targetName: "",
targetNameDashes: "",
guessRemain: 10,
lettersGuessed: []
};
// utility extracted from componentDidMount
// so that it can be re-used later
resetGame = () => {
let targetName = names[Math.floor(Math.random() * names.length)];
this.setState({
guessRemain: 10,
lettersGuessed: [],
targetName: targetName,
targetNameDashes: new Array(targetName.length).fill("-").join("") // fill an array with hyphens
});
};
componentDidMount() {
// call the utility
this.resetGame();
}
onKeyUp = event => {
event.preventDefault();
let letter = event.key.toUpperCase();
// TODO: provide more logic to avoid bad key strokes
// for example backspace should not count
if (letter) {
this.setState(
prevState => {
let modifiedNameDashes = String(prevState.targetNameDashes);
// for each charecter of targetName
for (var i = 0; i < prevState.targetName.length; i++) {
// check if this charecter at index i matched the key
if (prevState.targetName[i] === letter) {
// if it does
// remove a hyphen from modifiedNameDashes at that exact index
modifiedNameDashes =
modifiedNameDashes.substr(0, i) +
letter +
modifiedNameDashes.substr(i + 1);
}
}
return {
targetNameDashes: modifiedNameDashes,
guessRemain: prevState.guessRemain - 1,
lettersGuessed: [...prevState.lettersGuessed, letter]
};
},
// callback after the state update is done
() => {
// won
if (this.state.targetNameDashes === this.state.targetName) {
console.log("Nice!");
}
// lost
if (this.state.guessRemain === 0) {
this.resetGame();
}
}
);
}
};
render() {
return (
<div className="App">
<div>
You will be seen by:
<br />
{this.state.targetNameDashes}
</div>
<br />
<div>
Letters guessed:
<br />
<input onKeyUp={this.onKeyUp} />
<br />
Letters guessed in this round:
<br />[ {this.state.lettersGuessed} ]
</div>
<br />
<div>
Guesses remaining:
<br />
{this.state.guessRemain}
</div>
<code>{JSON.stringify(this.state)}</code>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
答案 1 :(得分:0)
targetNameDashes.replace(/-/gi, letter).toUpperCase();
this.setState({
targetNameDashes: targetNameDashes
// does it need a callback to update?
});
这很可能是您问题的根源,没有任何反应-String.prototype.replace
返回字符串的新版本,并且不修改参数字符串。
这至少会导致它进行更新,因此您可以继续处理此处的逻辑。
this.setState({
targetNameDashes: targetNameDashes.replace(/-/gi, letter).toUpperCase()
});