reactjs 在React中管理对话框的最佳方法

6l7fqoea  于 2023-02-15  发布在  React
关注(0)|答案(3)|浏览(125)

我想知道是否有更好的方法来管理功能组件中对话框的打开和关闭?您可以在下面找到一个示例:

import React, { useState } from 'react';
import PropTypes from 'prop-types';

import EditDialog from './EditDialog';
import DeleteDialog from './DeleteDialog';

const ContactCard = ({ contact }) => {
  const [editOpen, setEditOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);

  const handleEditOpen = () => {
    setEditOpen(true);
  };
  const handleEditClose = () => {
    setEditOpen(false);
  };
  const handleDeleteOpen = () => {
    setDeleteOpen(true);
  };
  const handleDeleteClose = () => {
    setDeleteOpen(false);
  };

  const { type, firstName, lastName, phoneNumber, mail } = contact;
  return (
    <>
      <div className={classes.main}>
        {/* All my contact informations */}
      </div>
      <EditDialog handleClose={handleEditClose} open={editOpen} />
      <DeleteDialog handleClose={handleDeleteClose} open={deleteOpen} />
    </>
  );
};

ContactCard.propTypes = {
  contact: PropTypes.object.isRequired
};

export default ContactCard;

我认为这是超级多余的,但我找不到更好的方法来管理几个不同的对话框。

const handleEditOpen = () => {
    setEditOpen(true);
  };
  const handleEditClose = () => {
    setEditOpen(false);
  };
  const handleDeleteOpen = () => {
    setDeleteOpen(true);
  };
  const handleDeleteClose = () => {
    setDeleteOpen(false);
  };

非常感谢您的时间和建议!

c9qzyr3d

c9qzyr3d1#

为了减少代码的冗余,可以在一个函数中设置打开/关闭,方法是切换当前状态。我的是内联的,但您仍然可以创建handleEdit函数并在那里切换状态。

import React, {useState} from "react";
import ReactDOM from "react-dom";

function App() {
  const [editCard, setEditCard] = useState(false)
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={() => setEditCard(!editCard)}>Toggle Edit</button>
      {editCard && <div>Card is open for editing</div>}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

这是另一个代码示例,我没有运行它,但它应该看起来像这样。

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import EditDialog from './EditDialog';
import DeleteDialog from './DeleteDialog';

const ContactCard = ({ contact }) => {
  const [editOpen, setEditOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);

  const handleEdit = () => {
    setEditOpen(!editOpen);
  };

  const handleDelete = () => {
    setDeleteOpen(!deleteOpen);
  };

  const { type, firstName, lastName, phoneNumber, mail } = contact;
  return (
    <>
      <div className={classes.main}>
        {/* All my contact informations */}
      </div>
      {
         editOpen && <EditDialog handleEdit={handleEdit} />
      }
      {
        deleteOpen && <DeleteDialog handleClose={handleClose} /> 
      }
    </>
  );
};

ContactCard.propTypes = {
  contact: PropTypes.object.isRequired
};

export default ContactCard;
ivqmmu1c

ivqmmu1c2#

打开对话框应该是主组件的职责。这样的话,只有当state属性为true时,模态才会被呈现。另一个技巧是使用<React.Fragment>而不是<>

import React, { useState } from 'react';
import PropTypes from 'prop-types';

import EditDialog from './EditDialog';
import DeleteDialog from './DeleteDialog';

const ContactCard = ({ contact }) => {
  const [editOpen, setEditOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);

  const handleEditOpen = () => {
    setEditOpen(!editOpen);
  };

  const handleDeleteOpen = () => {
    setDeleteOpen(!deleteOpen);
  };

  const { type, firstName, lastName, phoneNumber, mail } = contact;
  return (
    <React.Fragment>
      <div className={classes.main}>
        {/* All my contact informations */}
      </div>
      {
         editOpen && <EditDialog handleClose={handleEditOpen} />
      }
      {
        deleteOpen && <DeleteDialog handleClose={handleDeleteOpen} /> 
      }
    </React.Fragment>
  );
};

ContactCard.propTypes = {
  contact: PropTypes.object.isRequired
};

export default ContactCard;
xnifntxz

xnifntxz3#

为了封装改变对话框打开状态的逻辑,我建议创建单独的钩子:

const useToggle = (defaultValue) => {
  return useReducer((value) => !value, !!defaultValue)
}

这个钩子基本上是useState,但是setState函数不等待参数来更新状态,它用当前状态的逆来更新状态。
这在使用对话框时可能会很有用:

const ContactCard = () => {
  const [editOpen, toggleEditOpen] = useToggle(false);
  const [deleteOpen, toggleDeleteOpen] = usetoggle(false);

  return (
    <>
      <div className={classes.main}>
        {/* All my contact informations */}
      </div>
      {editOpen && <EditDialog handleEdit={toggleEditOpen} />}
      {deleteOpen && <DeleteDialog handleClose={toggleDeleteOpen} />}
    </>
  );
};

相关问题