Reactjs:将两个useState值作为输出



我有一个函数,它接受用户输入(字符串(,将每个字母转换为数字,然后返回它们的总和。我还有另一个函数,它检查和是否是素数。

const [data, setData] = useState([])
const [result, setResult] = useState([])
const [prime, setPrime] = useState([])

function getData(val) {
let value = val.target.value
value = value.replace(/[^A-Za-z]/ig, '')
setData(value)
console.warn(value)
}

function calculate() {
var result = 0
for (var i=0; i<data.length; i++) {
result += data[i].charCodeAt(0) - 96
}
setResult(result)
}
function isPrime() {
var prime = ''
for (var i = 2, s = Math.sqrt(result); i<s; i++) {
if (result % i == 0 || result <= 1) {
prime = ' which is not a prime number'
} else  {
prime = ' which is a prime number'
}
}
setPrime(prime)
}
function finalOutput() {
calculate()
isPrime()
}

我有一个带有onClick事件(finalOutput(的按钮,但useState prime似乎没有出现在我的网页上。

<form>
<input type="text" name="input" placeholder="Input Letters" className="footer-input" onChange={getData} />
<Button type="button" onClick={finalOutput}>Calculate</Button>
</form>
<p>{result}{prime}</p>

我认为这是因为setResult是异步工作的。因此,isPrime函数中使用的结果状态还没有值,因为该函数是立即执行的。因此,在setPrime中设置了一个空字符串。

对于解决方案,您可以使用useEffect,如下所示:

useEffect(() => {
// check if result is empty
if (result.length !== 0) {
isPrime();
}
}, [result]);

在上面的代码中,useEffect在结果状态更改时运行,在useEffect内部,isPrime函数在结果不为空时调用。

还有其他方法也像使用承诺,但我认为这应该做到

据我所知,您的输入只使用字母字符(大写和小写(,而不使用数字。而且,当你点击计算按钮时,你会想要数字格式的结果(通过将字母转换为相应的数值(。您可以首先更改状态以保持正确的初始值,因为值resultprime最终包含一个数字和一个字符串,所以将它们的初始状态设置为null''0''更有意义。

const [data, setData] = useState([])
const [result, setResult] = useState(null) //Null, if you are rendering the initial value on the screen
const [prime, setPrime] = useState('') //Empty string

getData函数中,您没有在每次击键时正确地将值附加到状态数组中。将值附加到数组的正确而好的方法是使用排列运算符(...(,您可以获取以前的值并将新接收的值附加到阵列。此外,请确保不要将空字符串值附加到数组中,因为空字符串的charCodeAt(0)返回NaN

function getData(val) {
let value = val.target.value.trim()
value = value.replace(/[^A-Za-z]/ig, '')
if(value!==''){
setData(prev=>[...prev,value]) //Appending new value using spread operator
}
console.warn(value)
}

此外,您可能希望在calculate函数中调用isPrime,因为设置状态是异步进程,并且您无法立即捕获设置的值。更新isPrime函数以接受结果作为参数。

function calculate() {
var result = 0
for (var i=0; i<data.length; i++) {
result += data[i].charCodeAt(0) - 96
}
setResult(result)
isPrime(result)
}

说到isPrime功能,它看起来还可以。既然没有使用finalOutput函数,您可以让按钮点击监听器指向calculate函数。总之,你的组件应该是这样的:

export default function Component(){
const [data, setData] = useState([])
const [result, setResult] = useState(null)
const [prime, setPrime] = useState('')

function getData(val) {
let value = val.target.value
value = value.replace(/[^A-Za-z]/ig, '')
// console.log(value)
setData(prev=>[...prev,value])
// console.warn(value)
}

function calculate() {
var result = 0
for (var i=0; i<data.length; i++) {
result += data[i].charCodeAt(0) - 96
}
// console.log(result)
setResult(result)
isPrime(result)
}
function isPrime(res) {

var prime = ''
for (var i = 2;,s = Math.sqrt(result);i<=s; i++) {
if (res % i === 0 || res <= 1) {
prime = ' which is not a prime number'
} else  {
prime = ' which is a prime number'
}
}
setPrime(prime)
}

return (
<div className="App">
<form>
<input type="text" name="input" placeholder="Input Letters" className="footer-input" onChange={getData} />
<button onClick={calculate}>Calculate</button>
</form>
<p>{result}{prime}</p>
</div>
);
}

最新更新