当我更改其中的表单值时手风琴关闭

Accordion closes when I change value of a form within it

我有一个手风琴,里面有一个文本表单(代码沙箱:https://codesandbox.io/live/1qr00im):

function MovementAccordion() {
  const [formInput, setFormInput] = useState('')

    return(
      <Accordion>
        <Card>
          <Accordion.Toggle
            as={Card.Header}
            eventKey="0">
            Accordian Header
          </Accordion.Toggle>
          <Accordion.Collapse eventKey="0">
            <Card.Body>
              Fill in the form:
              <Form.Control
                onChange={(event) => setFormInput(event.target.value)}
                type="text"
                placeholder="Enter input here" />
              <Button
                variant="primary"
                >
                  Add
              </Button>
            </Card.Body>
          </Accordion.Collapse>
        </Card>
      </Accordion>
    )
  }

我已将 onChange() 函数添加到表单,以便在表单更新时将其推送到状态。但是,只要更新表单,手风琴就会关闭。

如果我完全删除 onChange() 函数,表单可以正常工作,我可以随意更新它。只要包含 onChange() 就会出现问题。

我花了比我愿意承认的更多的时间来尝试解决这个问题,我被困住了。

根据您的 sandbox:-

  • 您不应该像调用普通 JSX functional component 那样调用您的 function。相反,你应该像正常的 function 一样调用它 - {PrimaryMovementAccordion()}

  • 如果你想像你现在这样的状态打电话。那么只有 SecondaryMovementAccordion 确实是 JSX functional component 才能实现。所以你需要像这样创建另一个 React Functional Component of SecondaryMovementAccordion,以使其工作:-

  • App.js:-

import React, { useState } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import "./styles.css";

import Accordion from "react-bootstrap/Accordion";
import Card from "react-bootstrap/Card";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";

import SecondaryMovementAccordion from "./SecondaryMovementAccordion";

export default function App() {
  const [newPrimary, setNewPrimary] = useState("");
  const [newSecondary, setNewSecondary] = useState("");

  return (
    <>
      {/* Incorrect way of calling normal function */}
      {/* <PrimaryMovementAccordion /> */}
      {/* correct way of calling a normal function */}
      {PrimaryMovementAccordion()}
      {/* correct way of calling a JSX Functional Component */}
      <SecondaryMovementAccordion
        newSecondary={newSecondary}
        setNewSecondary={setNewSecondary}
      />
      <p>Primary: {newPrimary}</p>
      <p>Secondary: {newSecondary}</p>
    </>
  );

  // Primary Accordian
  function PrimaryMovementAccordion() {
    return (
      <Accordion defaultActiveKey="0">
        <Card>
          <Accordion.Toggle as={Card.Header} eventKey="0">
            Form accordion
          </Accordion.Toggle>
          <Accordion.Collapse eventKey="0">
            <Card.Body>
              Fill in the form:
              <Form.Control
                type="text"
                placeholder="Enter secondary movement"
                value={newPrimary}
                onChange={(event) => setNewPrimary(event.target.value)}
              />
              <p>{newPrimary}</p>
            </Card.Body>
          </Accordion.Collapse>
        </Card>
      </Accordion>
    );
  }
}
  • SecondaryMovementAccordion.js:-
import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import "./styles.css";

import Accordion from "react-bootstrap/Accordion";
import Card from "react-bootstrap/Card";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";

const SecondaryMovementAccordion = ({ newSecondary, setNewSecondary }) => {
  return (
    <Accordion defaultActiveKey="0">
      <Card>
        <Accordion.Toggle as={Card.Header} eventKey="0">
          Form accordion
        </Accordion.Toggle>
        <Accordion.Collapse eventKey="0">
          <Card.Body>
            Fill in the form:
            <Form.Control
              type="text"
              placeholder="Enter secondary movement"
              value={newSecondary}
              onChange={(event) => setNewSecondary(event.target.value)}
            />
            <p>{newSecondary}</p>
          </Card.Body>
        </Accordion.Collapse>
      </Card>
    </Accordion>
  );
};

export default SecondaryMovementAccordion;

这是上面显示的工作 sandbox