web-dev-qa-db-ja.com

JSXでメモを使用しても安全ですか?

私はModalをメモしようとしていますが、ここで問題があります。

入力を変更するとき、モーダルコンポーネントを再レンダリングする必要はありません。

例:

Modal.tsxは次のようになります。

import React from "react";
import { StyledModalContent, StyledModalWrapper, AbsoluteCenter } from "../../css";

interface ModalProps {
  open: boolean;
  onClose: () => void;
  children: React.ReactNode
};

const ModalView: React.FC<ModalProps> = ({ open, onClose, children }) => {
  console.log("modal rendered");

  return (
    <StyledModalWrapper style={{ textAlign: "center", display: open ? "block" : "none" }}>
      <AbsoluteCenter>
        <StyledModalContent>
          <button
            style={{
              position: "absolute",
              cursor: "pointer",
              top: -10,
              right: -10,
              width: 40,
              height: 40,
              border: 'none',
              boxShadow: '0 10px 10px 0 rgba(0, 0, 0, 0.07)',
              backgroundColor: '#ffffff',
              borderRadius: 20,
              color: '#ba3c4d',
              fontSize: 18
            }}
            onClick={onClose}
          >
            X
          </button>
          {open && children}
        </StyledModalContent>
      </AbsoluteCenter>
    </StyledModalWrapper>
  );
};

export default React.memo(ModalView);

これが私がそれをラップした例です。

import React from 'react'
import Modal from './modal;

const App: React.FC<any> = (props: any) => {
  const [test, setTest] = React.useState("");
  const [openCreateChannelDialog, setOpenCreateChannelDialog] = React.useState(false);

  const hideCreateModalDialog = React.useCallback(() => {
    setOpenCreateChannelDialog(false);
  }, []);

  return (
    <>
      <input type="text" value={test} onChange={(e) => setTest(e.target.value)} />
      <button onClick={() => setOpenCreateChannelDialog(true)}>Create channel</button>

      <Modal
        open={openCreateChannelDialog}
        onClose={hideCreateModalDialog}
        children={<CreateChannel onClose={hideCreateModalDialog} />}
      />
    </>
};

Modalコンポーネントが再レンダリングされるたびに(入力テキストを変更したときに)children参照が作成されるため、Appが再レンダリングされます。

私がラップした場合、興味があることを知って<CreateChannel onClose={hideCreateModalDialog} /> React.useMemo()フック内

例:

  const MemoizedCreateChannel = React.useMemo(() => {
    return <CreateChannel onClose={hideCreateModalDialog} />
  }, [hideCreateModalDialog]);

Modal内の子プロップを変更します

から:

children={<CreateChannel onClose={hideCreateModalDialog} />}

children={MemoizedCreateChannel}

正常に動作しますが、安全ですか?そして、それは私がモーダルを思い出すために試みている唯一の解決策ですか?

4
Tazo Leladze

安全ですか?はい。結局のところ、JSXはJSONオブジェクトに変換されるだけであり、メモしておけばまったく問題ありません。

とはいえ、これを行うのは文体的には少し変だと思います。物事を変更する必要があり、十分に検討しなければ、将来的に予期しないバグにつながる可能性があります。

0
Bill Metcalf