简体   繁体   English

Reactjs:将两个useState值作为output

[英]Reactjs: putting two useState value as output

I have a function that takes a user input (strings) and convert each letters into numbers then returns the sum of them.我有一个 function 接受用户输入(字符串)并将每个字母转换为数字然后返回它们的总和。 I also have another function that checks if the sum is prime or not.我还有另一个 function 检查总和是否为素数。

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()
    }

I have a button with the onClick event (finalOutput) but useState prime doesn't seem to show up on my webpage.我有一个带有 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>

I think this is happening because setResult works asynchronously.我认为这是因为 setResult 是异步工作的。 So the result state used in isPrime function does not have the value yet as this function is executed immediately.因此,在 isPrime function 中使用的结果 state 还没有值,因为这个 function 会立即执行。 Therefore an empty string is being set in setPrime.因此在 setPrime 中设置了一个空字符串。

For the solution you can use useEffect like this:对于解决方案,您可以像这样使用 useEffect :

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

In the above code useEffect runs when result state changes and inside the useEffect, isPrime function is called when result is not empty.在上面的代码中,当结果 state 发生变化时运行 useEffect,并且在 useEffect 内部,当结果不为空时调用 isPrime function。

There are other ways too like using promises but I think this should do it.还有其他方法也可以使用 Promise,但我认为应该这样做。

As far as I've understood, your input takes only alphabetic characters (both upper case and lower case), but not numbers.据我了解,您的输入只需要字母字符(大写和小写),而不是数字。 And, when you click on the calculate button, you'd want the result in numeric format (by converting alphabets into their corresponding numeric values).而且,当您单击计算按钮时,您会希望得到数字格式的结果(通过将字母转换为相应的数值)。 You can firstly begin by changing the states to hold the correct initial values, since, the values result and prime hold a number and a string in the end, it'd make more sense to have their initial states be null and '' or 0 and '' .您可以首先更改状态以保存正确的初始值,因为值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

In your getData function, you are not correctly appending values on the state array on each keystroke.在您的getData function 中,您没有在每次击键时正确地在 state 数组上附加值。 The correct and good way to append values to the array would be to use the spread operator( ... ), you can get hold of the previous values and append the newly received value to the array.将 append 值添加到数组中的正确和好的方法是使用扩展运算符( ... ),您可以获取先前的值和 append 新接收到的值到数组中。 Also, make sure you don't append empty string values to the array, because charCodeAt(0) for an empty string returns NaN .另外,请确保不要将 append 空字符串值添加到数组中,因为空字符串的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)
}

Further, you'd want to call isPrime in your calculate function, as setting the state is asynchronous process and you wouldn't able to capture the set value immediately right after.此外,您需要在calculate function 中调用isPrime ,因为设置 state 是异步过程,您将无法立即捕获设置值。 Update your isPrime function to accept the result as an argument.更新您的isPrime function 以接受结果作为参数。

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

Coming to the isPrime function, it looks alright.来到isPrime function,看起来还不错。 Now that, finalOutput function isn't used, you could instead make the button click listener point to the calculate function.现在,未使用finalOutput function,您可以改为让按钮单击侦听器指向calculate function。 Altogether, your component should look, something like this:总而言之,您的组件应该看起来像这样:

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>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM