根据数字的值更改按钮上的文本 - 使用 Hooks 做出反应

Change text on button depending on value of a number - React using Hooks

我有一个计数器,它是我数组的索引,每次单击按钮都会显示下一个元素。我想要实现的是我希望在开头和索引再次变为 0 时显示特定文本,并在数字之间显示不同的文本。 到目前为止,这是我的代码,文本保持不变,但我不确定哪里出了问题。

function App() {


const questions_size = Data.length; 
  const [num, setNum] = useState(0);
  const current = Data[num].content;

  const [buttonText, setButtonText] = useState("Παιξε");
  const change_text = (text) => setButtonText(text);

  const callTwoFunc = () => {
    setNum(num + 1);
    setButtonText("Επομενο");
  }

  return (

  <div style={{ display: 'flex' }}>

          <Button variant="contained" color="primary" onClick={() => {  num < questions_size - 1 ? callTwoFunc() : setNum(0); change_text("Παιξε"); }}>{buttonText}</Button>
          <Card className={classes.root}>
            <CardContent>

              <Typography variant="body1" gutterBottom>

                <p style={{ fontFamily: 'Tangerine, serif', fontSize: '35px', textShadow: '4px 4px 4px #aaa' }}>{current}</p>
              </Typography>
            </CardContent>
          </Card>



  </div>


  );
}

export default App;

现在它只说“Παιξε”,但我希望它在我第一次点击后变成“επόμενο”,然后当 num 变为零时再次变成“Παιξε”。

这样做

num < questions_size - 1 ? callTwoFunc() : setNum(0); change_text("Παιξε");

运算符实际上像 num < questions_size - 1 ? callTwoFunc() : setNum(0); 一样,而在它之后,无论如何 change_text("Παιξε"); 都会 运行。将运算符更改为标准 if 语法,以便对每个案例都有一个块而不是只有一个表达式


       if (num < questions_size - 1) callTwoFunc()
       else { setNum(0); change_text("Παιξε"); }

或使用逗号运算符 - Javascript - Ternary Operator with Multiple Statements

问题出在按钮的 onClick 功能的 change_text('Παιξε'); 部分:

onClick={() => {
    num < questions_size - 1 ? callTwoFunc() : setNum(0);
    change_text('Παιξε');
  }}

它将始终将按钮更改为 Παιξε。将该逻辑移至 callTwoFunc:

更容易
const callTwoFunc = () => {
    setNum(prev => {
     if(prev < questions_size - 1) {
       return prev + 1;
     } else {
       return 0;
     }
   })
  }

而按钮只有两种状态,直接做比使用状态更简单:​​

<Button>{num === 0 ? "Παιξε" : "Επομενο" }</Button>
import React, {useState} from "react";
import "./styles.css";

export default function App() {
  const Data = [{content: ""},{content: ""}]
  const questions_size = Data.length; 
  const [num, setNum] = useState(0);
  // const current = Data[num].content;

  const [buttonText, setButtonText] = useState("Παιξε");
  const change_text = (text) => setButtonText(text);

  const callTwoFunc = () => {
    setNum(num + 1);
    change_text("Επομενο")
  }

  const handleClick = () => {
    console.log('click',num < questions_size - 1);
    if(num < questions_size - 1){
      callTwoFunc()
    }
    else{
      console.log('ding');
      setNum(0);
      change_text("Παιξε");
    }
  }

  return (
    <div className="App">
    <button variant="contained" color="primary" onClick={handleClick}>{buttonText}</button>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

尝试这样做......我猜它会起作用

正如我之前所说 破坏您代码的实际部分是在每次点击时调用 change_text("Παιξε");,因此 它将覆盖您的所有更改,因此克服此类问题的最佳做法是使 onClick 函数更通用。因此,您必须将所有逻辑传递给 callTwoFunc() 函数。其中一种做法是在您的函数中使用传统的 if-else

所以你的最终代码应该是这样的:

const callTwoFunc = () => {
  if (num < questions_size - 1) {
    setNum(num + 1)
    change_text('Επομενο')
  } else {
    setNum(0)
    change_text('Παιξε')
  }
}

return (
  <Button
    variant='contained'
    color='primary'
    onClick={() => {
      callTwoFunc()
    }}
  >
    {buttonText}
  </Button>
)

工作演示:

我不知道实际的 Data 是什么,所以我只是模拟它会空字符串。