【问题标题】:React hooks - Dynamically adding and deleting component. Delete problemReact hooks - 动态添加和删除组件。删除问题
【发布时间】:2020-08-06 11:39:18
【问题描述】:

CODESANDBOX 链接已提供!

应用创意的简短摘要: 在线考试应用程序包含两个组件:考试表格和问题。和上下文组件:考试。 考试表格包含用户所有动态添加的问题。 用户还可以删除问题。每个问题都有一个唯一的 ID。

预期功能: 问题存储在考试上下文数组中,可通过考试表格和问题访问。 所以这里的想法是,一旦用户单击问题的删除按钮,该问题将通过使用其 id 从上下文数组中删除,从而反映考试表单组件的更改。

问题: 假设用户添加了 3 个问题。 如果用户在第二个问题上点击删除,第三个问题将被删除,第二个问题将具有第三个问题的 id。如果他点击第一个,第二个将被删除。 更奇怪的是,用户在最后一个问题(比如第 3 个问题)上单击删除,该问题将被删除。

我想要的只是删除用户点击的问题而不干扰数组的其他元素。

请先检查代码再做假设,谢谢。

CODESANDBOX LINK

为了简单起见,我更改了原始代码和问题,并删除了大部分样式,仅用于演示目的。

【问题讨论】:

    标签: reactjs react-hooks react-context


    【解决方案1】:

    一些问题

    1. 每个问题的单选组名称都需要一个唯一的“名称”属性,因为选择任何问题的任何单选项目都会影响另一个问题。

    解决方案:将 id 属性值附加到 name 属性以创建每个问题的唯一名称组

    <input type="radio" name={`sport_${id}`} value="soccer" />
    
    1. 从问题中删除问题的逻辑不应存在于问题本身中。

    可能的解决方案:提供卡片调用的方法及其 id 以从数组中删除自身(参见下面的代码)

    1. 您的物品的渲染有点奇怪。而是将数据存储在一个数组中,并在返回方法中处理渲染。 不要忘记您的密钥道具,否则您的选择将丢失(最好也将其存储在状态中)

    exam.js

    export const ExamProvider = ({ children }) => {
      const [questions, setQuestions] = useState([]);
    
      const removeQuestion = (id) => {
        setQuestions((questions) => questions.filter((q) => q.id !== id));
      };
    
      return (
        <Exam.Provider
          value={{
            questions,
            setQuestions,
            removeQuestion
          }}
        >
          {children}
        </Exam.Provider>
      );
    };
    

    问题.js

    const Question = ({ i, id}) => {
      const { removeQuestion } = useContext(Exam);
    
      return (
        <div className="q-main">
          {id}
          <div className="q-title">
            <h4>Which sport are you interested in the most?</h4>
            <div className="options">
              1. Soccer
              <input type="radio" name={`sport_${id}`} value="soccer" />
              2. Basketball
              <input type="radio" name={`sport_${id}`} value="basketball" />
              3. Bjj
              <input type="radio" name={`sport_${id}`} value="bjj" />
              4. MMA
              <input type="radio" name={`sport_${id}`} value="mma" />
            </div>
            <div className="name">
              Write your name:
              <input type="text" />
            </div>
          </div>
          <div className="delete">
            <button className="deletebtn" onClick={() => removeQuestion(id)}>
              Delete
            </button>
          </div>
        </div>
      );
    };
    
    export default Question;
    

    ExamForm.js

    import React, { useState, useContext } from "react";
    import { Exam } from "../contexts/exam";
    import uniqid from "uniqid";
    import { IoIosAddCircle } from "react-icons/io";
    import Question from "./Question";
    
    const ExamForm = () => {
      const exam = useContext(Exam);
    
      const addQ = () => {
        const id = uniqid();
        exam.setQuestions((questions) => [
          ...questions,
          {
            id: id
          }
        ]);
      };
    
      return (
        <div className="form-main">
          <button onClick={addQ} className="addqcs">
            <IoIosAddCircle className="addicon" size={65} color="#0089d6" />
          </button>
          {exam.questions.map((q) => {
            return <Question key={q.id} i={exam.questions.length + 1} id={q.id} />;
          })}
        </div>
      );
    };
    
    export default ExamForm;
    

    CodeSandbox

    【讨论】:

      猜你喜欢
      • 2021-03-14
      • 2017-12-09
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      • 2020-06-03
      • 1970-01-01
      相关资源
      最近更新 更多