React - 防止渲染映射按钮

问题描述 投票:0回答:2

我通过地图创建了 4 个按钮。它们是测验应用程序的四个可能答案。

它们的状态通过一个函数 handleClick 更新。单击时,该函数会禁用按钮,检查答案是否为真,然后生成一个新问题,按钮内有新答案,然后重新激活按钮。这个想法是用户不能选择多个答案。

问题是,当我更改按钮的禁用状态时,它们会重新呈现,立即产生一个新问题。

按钮和点击:

const createReponse = () =>
    tableauDeReponse
      .sort((a, b) => a - b)
      .map((ele) => {
        return (
          <button
          disabled={disableButton}
            className={`Reponse-container`}
            onClick={handleClick}
            type="button"
            id={ele.toString()}
            key={ele}
          >
            {ele}
          </button>
        );
      });

const handleClick = (e) => {  
    console.log("click");
 
    //  setDisableButton(true) this creates the unwanted rerender
    if (Number(e.target.id) === bonneReponse) { //this changes the class depending if the answer is ture or not
      
      e.target.className = "Reponse-container goodAnswer";
    } else {
      e.target.className = "Reponse-container wrongAnswer";
    }
         
    delay(1500).then(() => {
       getMovie() //this creates the question and answers
       e.target.className = "Reponse-container"
     
    //  setDisableButton(true) this creates the unwanted rerender
  }  )
}

我基本上尝试了所有我能找到的关于条件渲染和阻止渲染的教程,但到目前为止做得很差。

提前致谢:)

reactjs asynchronous rendering react-state
2个回答
0
投票

我认为您可以通过使用以下代码创建一个新状态 selectedAnsId 来实现此目的。

const createReponse = () =>
   tableauDeReponse
    .sort((a, b) => a - b)
    .map((ele) => {
    return (
      <button
        disabled={disableButton}
        className={`Reponse-container ${ selectedAnsId === ele.toString() ? ele===correctAnswer ? "goodAnswer" :  "wrongAnswer" : ""}`}
        onClick={handleClick}
        type="button"
        id={ele.toString()}
        key={ele}
      >
        {ele}
      </button>
    );
 });

const handleClick = (e) => {  
  setDisableButton(true)
  setSelectedAnsId(e.target.id)
  // these two setState should be batched now
 
  delay(1500).then(() => {
   getMovie() //this creates the question and answers
   e.target.className = "Reponse-container";
  })
}

0
投票

您的“生成新问题”副作用似乎在用户与您的按钮交互后以某种方式执行。我似乎无法从您当前的代码中复制它。

但是,您应该在新问题提取或 getMovie 函数完成后设置按钮状态(禁用和类名)。

例如:

  const generateNewQuestion = (e) => {
    setTimeout(() => {
      setTotalQuestions(totalQuestions + 1);
      setDisableButton(false); // Enable your buttons to cause your rerender after all data fetching is complete
      e.target.className = "Reponse-container"; // Reset styles very last
    }, 1500);
  };

在此处查看工作示例https://codesandbox.io/s/react-prevent-rendering-of-mapped-buttons-chd130?file=/src/App.js

© www.soinside.com 2019 - 2024. All rights reserved.