You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JS问卷应用:实现问题堆叠显示的方案求助

实现React问卷应用的问题堆叠显示

当前代码通过单个状态存储当前问题,导致切换时旧问题被替换。要实现堆叠显示所有已作答问题,核心是维护一个已访问问题的历史数组,而非单个active项。具体修改方案如下:

1. 调整状态定义

将单个active状态替换为存储问题列表的数组,初始值包含首个问题:

const [questionHistory, setQuestionHistory] = React.useState<any[]>([
  data.preQuestions['landingPage']
]);

2. 更新切换问题的逻辑

点击按钮时,将新问题追加到历史数组末尾,而非替换当前项:

const loadNextComponent = (nextQuestion) => {
  setQuestionHistory(prev => [...prev, nextQuestion]);
};

3. 渲染所有历史问题

遍历questionHistory数组,逐个渲染每个问题组件,同时保留回退功能:

const renderQuestionComponents = () => {
  return (
    <div>
      {/* 仅当历史长度大于1时显示回退按钮 */}
      {questionHistory.length > 1 && (
        <button onClick={() => setQuestionHistory(prev => prev.slice(0, -1))}>
          上一个问题
        </button>
      )}
      {/* 遍历渲染所有已访问的问题 */}
      {questionHistory.map((question, index) => (
        <div key={index} style={{ margin: '20px 0', padding: '10px', border: '1px solid #eee' }}>
          <h1>{question.heading}</h1>
          {/* 仅最后一个问题显示操作按钮,避免重复操作 */}
          {index === questionHistory.length - 1 && (
            <>
              <button
                onClick={() =>
                  loadNextComponent(content[question.buttons.yesButton.action])
                }
              >
                {question.buttons.yesButton.text}
              </button>
              <button
                onClick={() =>
                  loadNextComponent(content[question.buttons.noButton.action])
                }
              >
                {question.buttons.noButton.text}
              </button>
            </>
          )}
        </div>
      ))}
    </div>
  );
};

完整修改后的代码

import React from 'react';

const data = {
  preQuestions: {
    landingPage: {
      heading: 'This is the landing page',
      buttons: {
        yesButton: {
          text: 'yes',
          action: '1A',
        },
        noButton: {
          text: 'No',
          action: '1B',
        },
      },
    },
    '1A': {
      heading: 'This is the 1A Component',
      buttons: {
        yesButton: {
          text: 'yes',
          action: '1C',
        },
        noButton: {
          text: 'No',
          action: '1D',
        },
      },
    },
    '1B': {
      heading: 'This is the 1B Component',
      buttons: {
        yesButton: {
          text: 'yes',
          action: '1C',
        },
        noButton: {
          text: 'No',
          action: '1D',
        },
      },
    },
    '1C': {
      heading: 'This is the 1C Component',
      buttons: {
        yesButton: {
          text: 'yes',
          action: '1A',
        },
        noButton: {
          text: 'No',
          action: '1B',
        },
      },
    },
    '1D': {
      heading: 'This is the 1D Component',
      buttons: {
        yesButton: {
          text: 'yes',
          action: '1B',
        },
        noButton: {
          text: 'No',
          action: '1C',
        },
      },
    },
  },
};

export default function App() {
  const [questionHistory, setQuestionHistory] = React.useState<any[]>([
    data.preQuestions['landingPage']
  ]);
  const content = data.preQuestions;

  const loadNextComponent = (nextQuestion) => {
    setQuestionHistory(prev => [...prev, nextQuestion]);
  };

  const renderQuestionComponents = () => {
    return (
      <div>
        {questionHistory.length > 1 && (
          <button onClick={() => setQuestionHistory(prev => prev.slice(0, -1))} style={{ marginBottom: '10px' }}>
            上一个问题
          </button>
        )}
        {questionHistory.map((question, index) => (
          <div key={index} style={{ margin: '20px 0', padding: '15px', border: '1px solid #ddd', borderRadius: '4px' }}>
            <h1>{question.heading}</h1>
            {index === questionHistory.length - 1 && (
              <>
                <button
                  onClick={() => loadNextComponent(content[question.buttons.yesButton.action])}
                  style={{ marginRight: '10px' }}
                >
                  {question.buttons.yesButton.text}
                </button>
                <button
                  onClick={() => loadNextComponent(content[question.buttons.noButton.action])}
                >
                  {question.buttons.noButton.text}
                </button>
              </>
            )}
          </div>
        ))}
      </div>
    );
  };

  return <div>{renderQuestionComponents()}</div>;
}

关键说明

  • 用数组questionHistory保存所有已访问问题,确保切换时旧问题不会被覆盖
  • 仅最后一个问题显示操作按钮,避免用户误操作历史问题
  • 新增回退按钮,通过截取数组实现回到上一步的功能

内容的提问来源于stack exchange,提问作者azhagu droptaxi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:55:27