reactjs 如何创建可编辑的文本框

y0u0uwnf  于 12个月前  发布在  React
关注(0)|答案(1)|浏览(144)

我正在尝试为我的食谱博客创建可编辑的文本框。这里是帖子表单,用户可以通过键入他们的步骤来添加食谱说明,点击加号添加按钮,然后看到他们的步骤布局在textarea下面。我可以双击文本框并获得输入来更新文本,然而,我在将更新的值设置为前一个空间中的新文本时遇到了问题。如果我没有包含足够的上下文here,我将链接我的github页面,您可以在那里查看完整的文档

const [instructionsList, setInstructionsList] = useState<Instruction[]>([]);
  const [isEditMode, setIsEditMode] = useState(false);

 const changeEditMode = () => {
    setIsEditMode((prevState) => !prevState);
  };

  const updateEditMode = () => {
    setIsEditMode(false);
  };

 const handleAddInstruction = (e: React.FormEvent) => {
    e.preventDefault();
    const instructionListObj = {
      id: uniqid(),
      index: instructionsList?.length + 1,
      content: instructionRef.current!.value,
    };

    const allInstructions = [...instructionsList, instructionListObj];
    setInstructionsList(allInstructions);

    instructionRef.current!.value = "";
  };

字符串
//返回部分

<section className={`${styles.section5} ${styles.section}`}>
            <div className={styles.field}>
              <div className={styles["input-field"]}>
                <h1 className={styles.label}>instructions</h1>
                <textarea
                  name="instruction"
                  id="instruction"
                  className={styles.textarea}
                  ref={instructionRef}
                  rows={8}
                  placeholder="add a step"
                ></textarea>
                <button
                  onClick={handleAddInstruction}
                  className={styles.submit}
                >
                  <i className="fa-solid fa-plus"></i>
                </button>
              </div>

// THIS IS WHERE THE STEPS ARE OUTPUTED

              <ul className={styles["instructions-list"]}>
                {instructionsList.map(
                  (instruction: {
                    id: string;
                    index: number;
                    content: string;
                  }) => (
                    <li
                      key={instruction.id}
                      className={styles["instructions-list-item"]}
                      onDoubleClick={changeEditMode}
                    >
                      <p className={styles.index}>step {instruction.index}</p>
                      <p className={styles.content}>
                        {isEditMode ? (
                          <span>
                            <input
                              className={styles.edit}
                              type="text"
                              defaultValue={instruction.content}
                              id="edit"
                              name="edit"
                            />
                            <button onClick={updateEditMode} type="button">
                              OK
                            </button>
                            <button onClick={changeEditMode} type="button">
                              X
                            </button>
                          </span>
                        ) : (
                          instruction.content
                        )}
                      </p>
                    </li>
                  )
                )}
              </ul>
            </div>
          </section>


我也注意到,当我双击文本框编辑文本,所有的文本框变成输入编辑,在那里这不是一个真正的问题美学,我想也许一旦我解决了更新值的问题,它会改变所有的文本值时,我只是想改变一个.帮助!!

gmxoilav

gmxoilav1#

您最好创建一个组件来容纳指令列表项,这些指令列表项可以将其isEditing状态和其中发生的任何草稿编辑分开。

interface InstructionProps extends Instruction {
  update: (instruction: Instruction) => void;
}

const InstructionComponent: React.FC<InstructionProps> = ({
  content,
  index,
  id,
  update
}) => {
  const [isEditing, setIsEditing] = useState(false);
  const [contentDraft, setContentDraft] = useState(content);

  const updateContent = () => {
    update({ id, index, content: contentDraft });
    setIsEditing(false);
  };

  const toggleEdit = () => setIsEditing(editing => !editing);
  
  return (
     <li
       className={styles["instructions-list-item"]}
       onDoubleClick={toggleEdit}
     >
       <p className={styles.index}>step {index}</p>
         <p className={styles.content}>
           {isEditing ? (
             <span>
               <input
                className={styles.edit}
                type="text"
                defaultValue={content}
                value={contentDraft}
                onChange={e => setContentDraft(e.target.value)}
                id="edit"
                name="edit"
               />
               <button onClick={updateContent} type="button">
                  OK
               </button>
               <button onClick={toggleEdit} type="button">
                 X
               </button>
              </span>
            ) : content
          }
         </p>
      </li>
  );
}

const InstructionsContainer: React.FC = () => {
  const [instructionsList, setInstructionsList] = useState<Instruction[]>([]);

  const updateInstructionsList = (instruction: Instruction) => {
    const instructionIndex = instructionsList.findIndex(i => i.id === instruction.id);
    if(instructionIndex > -1) {
      setInstructionList(instructionsList => {
        instructionsList.splice(instructionIndex, 1, instruction);
        return [...instructionsList];
      });
    }
  }

  return (
    {/*...all your other stuff*/}
    <ul className={styles["instructions-list"]}>
       {instructionsList.map(
          (instruction: Instruction) =>
            <InstructionComponent
              key={id}
              update={updateInstructionsList}
              {...instruction}
            />
       }
    </ul>
  );
}

字符串
这允许你将草稿状态分离到它自己的组件中,并且只有在你准备好提交时才更新实际的最终状态。这里需要注意的是,在编辑instructionsList状态时,我们必须返回一个全新的数组,以确保React理解状态实际上已经改变。

相关问题