You need to enable JavaScript to run this app. React.js如何限制单组问卷列表渲染的问题数量最多为4个
优惠活动
大模型
产品
解决方案
定价
更多

React.js如何限制单组问卷列表渲染的问题数量最多为4个

React问卷应用实现方案

需求描述

  • 用户点击创建按钮即可生成一道附带4个选项的问卷问题
  • 单个问卷列表最多容纳4个问题,最少保留1个问题
  • 已有4个问题的列表中新增问题时,自动创建新的问卷列表

原有代码梳理

Survey.js

import React, { useState, useEffect } from "react";
import { Fragment } from "react";
import "./Survey.css";
import CreateSurvey from "../modals/CreateSurvey";
import Card from "../card/Card";

const Survey = () => {
  const [modal, setModal] = useState(false);
  const [surveyList, setSurveyList] = useState([]);

  useEffect(() => {
    let arr = localStorage.getItem("surveyList");
    if (arr) {
      let obj = JSON.parse(arr);
      setSurveyList(obj);
    }
  }, []);

  const deleteSurvey = (index) => {
    let tempList = surveyList;
    tempList.splice(index, 1);
    localStorage.setItem("surveyList", JSON.stringify(tempList));
    setSurveyList(tempList);
    window.location.reload();
  };

  const toggle = () => {
    setModal(!modal);
  };

  const updateListArray = (obj, index) => {
    let tempList = surveyList;
    tempList[index] = obj;
    localStorage.setItem("surveyList", JSON.stringify(tempList));
    setSurveyList(tempList);
    window.location.reload();
  };

  const saveSurvey = (surveyObj) => {
    let tempList = surveyList;
    tempList.push(surveyObj);
    localStorage.setItem("surveyList", JSON.stringify(tempList));
    setSurveyList(surveyList);
    setModal(false);
  };
  return (
    <Fragment>
      <div className="header text-center">
        <h5>问卷</h5>
        <button className="btn btn-primary" onClick={() => setModal(true)}>
          创建问卷
        </button>
      </div>
      <div className="survey-container">
        {surveyList &&
          surveyList.map((obj, index) => (
            <Card
              surveyObj={obj}
              index={index}
              deleteSurvey={deleteSurvey}
              updateListArray={updateListArray}
            >
              <input type="radio" name="answerOne" />
            </Card>
          ))}
      </div>
      <CreateSurvey toggle={toggle} modal={modal} save={saveSurvey} />
    </Fragment>
  );
};

export default Survey;

Card.js

import React, { useState } from "react";
import "./Card.css";
import EditSurvey from "../modals/EditSurvey";

const Card = ({ surveyObj, deleteSurvey, index, updateListArray }) => {
  const [modal, setModal] = useState(false);

  const toggle = () => {
    setModal(!modal);
  };

  const updateSurvey = (obj) => {
    updateListArray(obj, index);
  };

  const deleteHandler = () => {
    deleteSurvey(index);
  };

  return (
    <div>
      <div className="card-wrapper mr-5">
        <div className="card-top"></div>
        <div className="survey-holder">
          <span className="card-headers">{surveyObj.name}</span>
          <span className="check">
            <input type="radio" className="radio" />
            <p className="answer"> {surveyObj.answerOne}</p>
          </span>
          <span className="check">
            <input type="radio" className="radio" />
            <p className="answer"> {surveyObj.answerTwo}</p>
          </span>
          <span className="check">
            <input type="radio" className="radio" />
            <p className="answer"> {surveyObj.answerThree}</p>
          </span>
          <span className="check">
            <input type="radio" className="radio" />
            <p className="answer"> {surveyObj.answerFour}</p>
          </span>
          <div className="icons">
            <i className="far fa-edit edit" onClick={() => setModal(true)}></i>
            <i className="fas fa-trash-alt delete" onClick={deleteHandler}></i>
          </div>
        </div>
        <EditSurvey
          modal={modal}
          toggle={toggle}
          updateSurvey={updateSurvey}
          surveyObj={surveyObj}
        />
      </div>
    </div>
  );
};

export default Card;

CreateSurvey.js

import React, { useState } from "react";
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import { Fragment } from "react";

const CreateSurvey = ({ modal, toggle, save }) => {
  const [question, setQuestion] = useState("");
  const [answerOne, setAnswerOne] = useState("");
  const [answerTwo, setAnswerTwo] = useState("");
  const [answerThree, setAnswerThree] = useState("");
  const [answerFour, setAnswerFour] = useState("");

  const changeHandler = (e) => {
    const { name, value } = e.target;

    if (name === "question") {
      setQuestion(value);
    } else if (name === "answerOne") {
      setAnswerOne(value);
    } else if (name === "answerTwo") {
      setAnswerTwo(value);
    } else if (name === "answerThree") {
      setAnswerThree(value);
    } else {
      setAnswerFour(value);
    }
  };

  const saveHandler = (e) => {
    e.preventDefault();
    let surveyObj = {};
    surveyObj["name"] = question;
    surveyObj["answerOne"] = answerOne;
    surveyObj["answerTwo"] = answerTwo;
    surveyObj["answerThree"] = answerThree;
    surveyObj["answerFour"] = answerFour;
    save(surveyObj);
  };
  return (
    <Fragment>
      <Modal isOpen={modal} toggle={toggle}>
        <ModalHeader toggle={toggle}>创建问卷问题</ModalHeader>
        <ModalBody>
          <form>
            <div>
              <div className="form-group">
                <label>问卷问题</label>
                <input
                  type="text"
                  className="form-control"
                  value={question}
                  name="question"
                  onChange={changeHandler}
                />
              </div>
            </div>
            <div className="mt-2">
              <label>问卷选项</label>
              <div className="form-group">
                <label>选项1</label>
                <input
                  type="text"
                  className="form-control mt-2 mb-2"
                  value={answerOne}
                  name="answerOne"
                  onChange={changeHandler}
                />
              </div>
              <div className="form-group">
                <label>选项2</label>
                <input
                  type="text"
                  className="form-control mt-2 mb-2"
                  value={answerTwo}
                  name="answerTwo"
                  onChange={changeHandler}
                />
              </div>
              <div className="form-group">
                <label>选项3</label>
                <input
                  type="text"
                  className="form-control mt-2 mb-2"
                  value={answerThree}
                  name="answerThree"
                  onChange={changeHandler}
                />
              </div>
              <div className="form-group">
                <label>选项4</label>
                <input
                  type="text"
                  className="form-control mt-2 mb-2"
                  value={answerFour}
                  name="answerFour"
                  onChange={changeHandler}
                />
              </div>
            </div>
          </form>
        </ModalBody>
        <ModalFooter>
          <Button color="primary" onClick={saveHandler}>
            创建
          </Button>
          <Button color="secondary" onClick={toggle}>
            取消
          </Button>
        </ModalFooter>
      </Modal>
    </Fragment>
  );
};

export default CreateSurvey;

自动分组功能修改实现

原有代码采用一维数组存储所有问题,无法满足分组要求,仅需修改Survey.js逻辑即可,其他文件无需改动:

// 修改后的Survey.js
import React, { useState, useEffect } from "react";
import { Fragment } from "react";
import "./Survey.css";
import CreateSurvey from "../modals/CreateSurvey";
import Card from "../card/Card";

const Survey = () => {
  const [modal, setModal] = useState(false);
  // 改为二维数组存储,每个子数组对应一个问卷列表
  const [surveyGroups, setSurveyGroups] = useState([[]]);

  useEffect(() => {
    let arr = localStorage.getItem("surveyGroups");
    if (arr) {
      let obj = JSON.parse(arr);
      setSurveyGroups(obj);
    }
  }, []);

  const toggle = () => {
    setModal(!modal);
  };

  const saveSurvey = (surveyObj) => {
    let tempGroups = JSON.parse(JSON.stringify(surveyGroups));
    const lastGroup = tempGroups[tempGroups.length - 1];
    if(lastGroup.length < 4) {
      // 最后一个分组未满则直接添加
      lastGroup.push(surveyObj);
    } else {
      // 最后一个分组已满则新建分组
      tempGroups.push([surveyObj]);
    }
    localStorage.setItem("surveyGroups", JSON.stringify(tempGroups));
    setSurveyGroups(tempGroups);
    setModal(false);
  };

  const deleteSurvey = (groupIndex, questionIndex) => {
    let tempGroups = JSON.parse(JSON.stringify(surveyGroups));
    tempGroups[groupIndex].splice(questionIndex, 1);
    // 删完如果分组为空且不是最后一个分组,就删除空分组
    if(tempGroups[groupIndex].length === 0 && tempGroups.length > 1) {
      tempGroups.splice(groupIndex, 1);
    }
    localStorage.setItem("surveyGroups", JSON.stringify(tempGroups));
    setSurveyGroups(tempGroups);
    window.location.reload();
  };

  const updateListArray = (obj, groupIndex, questionIndex) => {
    let tempGroups = JSON.parse(JSON.stringify(surveyGroups));
    tempGroups[groupIndex][questionIndex] = obj;
    localStorage.setItem("surveyGroups", JSON.stringify(tempGroups));
    setSurveyGroups(tempGroups);
    window.location.reload();
  };

  return (
    <Fragment>
      <div className="header text-center">
        <h5>问卷</h5>
        <button className="btn btn-primary" onClick={() => setModal(true)}>
          创建问卷
        </button>
      </div>
      <div className="survey-container">
        {surveyGroups && surveyGroups.map((group, groupIndex) => (
          <div key={groupIndex} className="survey-group" style={{marginBottom: '30px'}}>
            <h6>问卷列表 {groupIndex + 1}</h6>
            <div className="group-cards" style={{display: 'flex', gap: '20px', flexWrap: 'wrap'}}>
              {group.map((obj, questionIndex) => (
                <Card
                  key={questionIndex}
                  surveyObj={obj}
                  index={questionIndex}
                  deleteSurvey={(index) => deleteSurvey(groupIndex, index)}
                  updateListArray={(obj, index) => updateListArray(obj, groupIndex, index)}
                >
                  <input type="radio" name={`answer_${groupIndex}_${questionIndex}`} />
                </Card>
              ))}
            </div>
          </div>
        ))}
      </div>
      <CreateSurvey toggle={toggle} modal={modal} save={saveSurvey} />
    </Fragment>
  );
};

export default Survey;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 00:36:04