Bootstrap Modal 导致 useEffect({...}, []) 再次触发

问题描述 投票:0回答:1

使用 Bootstrap

<Modal />
组件时,当我对父组件进行回调时,我的入口页面会重新渲染,并触发我的
useEffect({...}, [])
-Hook,它应该只被调用一次,再次被调用,但我不知道为什么。

我的设置:NextJS、ReactJS、Bootstrap-React

Home() - Parent

export default function Home() {
  //data and internal logic states, table-content, which rows are selected, is the data still loading, etc.
  const [loading, setLoading] = useState(true);
  const [dataZähler, setDataZähler] = useState<ZählerObjekt[]>([]);
  const [dataProtokoll, setDataProtokoll] = useState<ProtokollEintrag[]>([]);
  const [selectedRowZähler, setSelectedRowZähler] = useState(-1);
  const [selectedRowProtokoll, setSelectedRowProtokoll] = useState(-1);
  //View-Logic states, which table is shown, if modals should be seen, etc
  const [showCreateZählerModal, setShowCreateZählerModal] = useState(false);

  //on start, load both csv's into states
  useEffect(() => {
    fetch('/api/loadCsv')
      .then((res) => res.json())
      .then((data) => {
        setDataZähler(data.dataZähler)
        setDataProtokoll(data.DataProtokoll)
        setLoading(false)
      })
  }, []);

  //rendering logic, the page only needs the data to work, so thats all thats needed, otherwise, show an error and have the user restart
  if (loading) return <p>loading ...</p>
  if (!dataZähler) return <p>No data on counters was found!</p>
  if (!dataProtokoll) return <p>No data on entries was found!</p>

  return (
    <div className="flex flex-col">
      <table> /* contains data, that gets edited when the modal is used/calls its callback */ </table>
      {/*Modal Div - all edit/Cancel/Save/Create/Delete modals go here*/}
      <div>
        <Modal size="lg" show={showCreateZählerModal} onHide={() => setShowCreateZählerModal(false)}>
          <Modal.Header closeButton>
            <Modal.Title>
              Neuen Zähler hinzufügen:
            </Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <CreateCounterPopUp data={dataZähler[0]} callback={(data) => {
              if (data)
                setDataZähler([...dataZähler, data]);
              setShowCreateZählerModal(false);
            }} />
          </Modal.Body>
        </Modal>
      </div>
    </div>
  );
}

CreateCounterPopUp() - Child

interface CounterProps {
    data: ZählerObjekt, //seed the PopUp
    callback: ZählerCallback //(only requires a Zählerobjekt)
}

export function CreateCounterPopUp({ data, callback }: CounterProps) {
    const [newCounter, setNewCounter] = useState(new ZählerObjekt());

    function handleSpeichern() { //dont forget to set the id of the new object
        setNewCounter({ ...newCounter, ...{ id: generateGenericObjectID(newCounter) } });
        callback(newCounter);
    }

    function handleInputChange(field: string, event: ChangeEvent<HTMLInputElement>) {
        const newState = { ...newCounter };
        newState[field as keyof ZählerObjekt] = event.target.value;
        setNewCounter(newState);
    }

    return (
        <div>
            <form>
                {Object.entries(newCounter).slice(1).map((elem, idx) => {
                    return (
                        <Form.Group
                            className="mb-3" key={idx} controlId={elem[0]}
                        >
                            <Form.Label>{elem[0]}</Form.Label>
                            <Form.Control
                                as="textarea"
                                rows={2}
                                placeholder={"z.B. " + String(data[elem[0] as keyof ZählerObjekt])}
                                onChange={(e) => handleInputChange(elem[0], e as any)} />
                        </Form.Group>
                    );
                })}
                <div className="float-right">
                    <button onClick={handleSpeichern} className="bg-[#22c55e] border-[none] text-[white] text-center inline-block text-base rounded-[5px] px-5 py-3 my-2">Speichern</button>
                </div>
            </form>
        </div>
    );
}

我尝试将页面的大小减小到最重要的部分,但是任何人都可以告诉我为什么当模态使用回调时模态会触发完整的

Home()
重新渲染,而不是当其
onHide()
属性为打电话了?

javascript reactjs next.js bootstrap-modal react-bootstrap
1个回答
0
投票

错误是React还在后台调用了一些其他函数,因此崩溃了。

function handleSpeichern(event: React.MouseEvent<HTMLButtonElement>) {
    event.preventDefault();
    {...}
}

防止默认事件发生保存了代码。

© www.soinside.com 2019 - 2024. All rights reserved.