首页 > 解决方案 > 尝试在单击触发渲染后使按钮保持突出显示

问题描述

我正在构建一个调查,现在我有一个组件,它接受一系列带有条件的问题并呈现一个问题,然后在用户单击后根据条件是否满足呈现下一个问题。当单击其中一个答案按钮(例如 Q1)时,它会使用 css 焦点更改颜色以向用户突出显示所选答案,问题是当出现下一个问题(例如 Q2)并单击下一个答案时,突出显示来自第一个问题的答案恢复为默认值,仅突出显示第二个问题的答案。

有没有办法使用 css 突出显示所有选择的答案,或者我必须对组件本身进行更改。

到目前为止,代码如下所示

const QuestionBox = ({ question, answer, onSelect }) => {
  const { questions, answers } = question;
  return (
    <div>
      <p>
        {question.question}
        <br/>
        {answers.map((text, index) => (
          <button
            className='questionBtns'
            key={index}
            onClick={() => {
              onSelect(text);
            }}
          >
            {text}
          </button>
        ))}
      </p>
    </div>
  );
};
export default QuestionBox;

class Survey extends Component {
   state = {
      answers: {};
   };

   render() {
     return (
       <div>                 
          {questions.map(question => (
              <QuestionBox
                  question={question}
                  answer={this.state.answers[question.questionId]}
                  key={question.questionId}
                  onSelect={answer => {
                       const answers = {
                            ...this.state.answers,
                            [question.questionId]: answer,
                   };
                  this.setState({ answers });
                 }}
                />
            ))}                       
          </div>

标签: javascriptcssreactjs

解决方案


// Question box should only know these things:
// 1. a single question
// 2. choices for that question
//   - each choice should have an id and text
// 3. function to select one of the choices
// 4. previously selected choice

// I have renamed and restructured stuff which is better suited in this scenario

const QuestionBox = ({ question, choices, selectChoice, previouslySelectedChoiceID }) => {

    // if some choice is already selected, highlight the button
    const buttonStyleClass = previouslySelectedChoiceID !== -1 ?  "some-hightlight-class" : "normal-class";

    return (
    <div>
      <p>
        {question}
        <br/>
        {choices.map(choice => (
          <button
            key={choice.id}
            onClick={() => {
                selectChoice(question.id, choice.id);
            }}
            className={buttonStyleClass}
          >
            {choice.text}
          </button>
        ))}
      </p>
    </div>
  );
};
export default QuestionBox;

//---------------------------------------------------
class Survey extends Component {
   state = {
      selectedChoices: [],
       // structure : 
      // [ { questionID : x, selectedChoiceID : y } ]
      questions: [], // assuming that questions are stored in state
      // structure : 
      // [ { id: x, text: x, choices: [ {id: y, text: z} ]}]
   };

   getSelectedChoiceForQuestionId = (questionID) =>{
        const {selectedChoices} = this.state;
        const index =  selectedChoices.findIndex( ch => ch.questionID === questionID) ;
        return index === -1 ? -1 : selectedChoices[index].selectedChoiceID;
   }

   handleSelectChoice = (questionID, selectedChoiceID) => {
       const {selectedChoices} = this.state;
        const index = selectedChoices.findIndex(x => x.questionID === questionID);
        // if selection is done for the first time,
        if (index === -1){
            selectedChoices.push({questionID, selectedChoiceID}); // shorthand
        }
        // else change the selection to something else
        // if you only want the users to select once only, remove the else part
        else{
            selectedChoices[index].selectedChoiceID = selectedChoiceID;
        }

   }

   render() {
    const {questions} = this.state;
     return (
       <div>                 
          {questions.map(question => (
              <QuestionBox
                  question={question.text}
                  choices={question.choices}
                  previouslySelectedChoiceID={this.getSelectedChoiceForQuestionId(question.id)}
                  selectChoice={this.handleSelectChoice}
                  key={question.id}
                />
            ))}                       
          </div>
     )}

}

推荐阅读