如何避免在 React 组件中钻取 props?

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

我知道这是一个有点多余的问题,但我在我的 React 应用程序中面临着一个特定的挑战,我希望有人可以帮助解决。我有一个组件需要从父组件传递多个 props,并且它的管理变得越来越复杂。

虽然我知道有 Context API 或 Redux 之类的替代方案用于状态管理,但在这种情况下,并非所有状态都在组件之间共享,并且为单个组件设置全局状态似乎有些过分。我仍然想在我的代码中保持良好的实践。

这是我的组件的片段:

<WorkPermitForm
  isMasterView={isMasterView}
  setIsMasterView={setIsMasterView}
  entryFormik={entryFormik}
  nameList={nameList}
  handleNameSelected={handleNameSelected}
  viewMode={viewMode}
  createMode={createMode}
  typeList={typeList}
  handleTypeSelect={handleTypeSelect}
  titleList={titleList}
  countryList={countryList}
  onCountryChange={onCountryChange}
  stateList={stateList}
  onStateChange={onStateChange}
  cityList={cityList}
  idCardList={idCardList}
  statusList={statusList}
  onUpload={onUpload}
  itemTemplate={itemTemplate}
  imageUrl={imageUrl}
  handleInputChange={handleInputChange}
  formData={formData}
  formRef={formRef}
  formik={formik}
  onVisitorTypeChange={onVisitorTypeChange}
  temporaryStateList={temporaryStateList}
  temporaryCityList={temporaryCityList}
  handleImageClose={handleImageClose}
  handleChange={handleChange}
  uploadRef={uploadRef}
  handleHyperlink={handleHyperlink}
  onUploadDocument={onUploadDocument}
  removeDocuments={removeDocuments}
  documentUrl={documentUrl}
  documentUploadRef={documentUploadRef}
  notification={notification}
  setBelongingDetailList={setBelongingDetailList}
  belongingDetailList={belongingDetailList}
  modeType={modeType}
  isCameraOff={isCameraOff}
  setCameraStatus={setCameraStatus}
  phoneNumber={phoneNumber}
/>

export const WorkPermitForm = (props) => {
  const {
    isMasterView,
    setIsMasterView,
    entryFormik,
    nameList,
    handleNameSelected,
    viewMode,
    createMode,
    typeList,
    handleTypeSelect,
    titleList,
    countryList,
    onCountryChange,
    stateList,
    onStateChange,
    cityList,
    idCardList,
    statusList,
    onUpload,
    itemTemplate,
    imageUrl,
    handleInputChange,
    formData,
    formRef,
    formik,
    onVisitorTypeChange,
    temporaryStateList,
    temporaryCityList,
    handleImageClose,
    handleChange,
    uploadRef,
    handleHyperlink,
    onUploadDocument,
    removeDocuments,
    documentUrl,
    documentUploadRef,
    notification,
    setBelongingDetailList,
    belongingDetailList,
    modeType,
    isCameraOff,
    setCameraStatus,
    phoneNumber,
    openDetails,
  } = props;

我正在寻找有关如何重组组件或使用替代模式(如 Context API 或 Redux)来管理状态并避免 props 钻探的建议。有哪些有效的策略或最佳实践?

我有这种成组传递的道具

  productDetails,
  pricingDetails,
  inventoryDetails,
  shippingDetails,
}) => {

  const {
    productName,
    productDescription,
    productImages,
    handleProductChange,
  } = productDetails;

  const {
    price,
    discount,
    currency,
    handlePriceChange,
  } = pricingDetails;

  const {
    stock,
    sku,
    handleStockChange,
  } = inventoryDetails;

  const {
    shippingOptions,
    selectedShipping,
    handleShippingChange,
  } = shippingDetails;

即使在组中,这也不是高效的,我想像对象一样传递给组件

<WorkPermitForm
  workPermitProp={...workPermitProp}
/>
reactjs performance structure react-props
2个回答
-1
投票

我能想到一些优化。

  1. 我看到您正在使用几个列表,例如 titleList、countryList、stateList、cityList。你把它们分组在一个州级别,像这样

    const [lists, setLists ] = useState({
     titleList: [],
     countryList: [],
     stateList: [] // and many more.
    })
    

    这样你就不会有很多状态或变量。

  2. 由于我没有完整代码的上下文,但我建议您在许多子组件中破坏 WorkPermitForm 组件,这样管理道具会更容易。

  3. 如果您是初学者并且仍然感到困惑,那么我建议您从 chatGPT 获得一些提示。作为一名全栈开发人员,我经常使用它。

注意:如果你想访问组件不同级别的状态,你必须使用 context api。就你而言,我认为没有必要。

所有最好的伙伴!


-1
投票
  1. 将全局状态移至 Redux: 确定哪些 props 在多个组件之间共享或深度嵌套。这些都是迁移到 Redux 的良好候选者,因为 Redux 允许集中状态管理。

为表单数据创建切片或缩减器(例如,workPermitFormSlice)。 可以为表单操作创建操作(如 setIsMasterView、handleInputChange、onCountryChange 等)。

// workPermitFormSlice.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  isMasterView: false,
  nameList: [],
  typeList: [],
  // Other relevant form states...
};

const workPermitFormSlice = createSlice({
  name: 'workPermitForm',
  initialState,
  reducers: {
    setIsMasterView: (state, action) => {
      state.isMasterView = action.payload;
    },
    setNameList: (state, action) => {
      state.nameList = action.payload;
    },
    // Other reducers for handling form updates...
  },
});

export const { setIsMasterView, setNameList } = workPermitFormSlice.actions;
export default workPermitFormSlice.reducer;

  1. 访问组件中的 Redux 状态和调度操作: 使用 useSelector 访问 Redux 状态并使用 useDispatch 触发状态更改,而不是沿着组件树传递 props

import { useDispatch, useSelector } from 'react-redux';
import { setIsMasterView, setNameList } from './workPermitFormSlice';

const WorkPermitForm = () => {
  const dispatch = useDispatch();

  // Access state from Redux store
  const isMasterView = useSelector((state) => state.workPermitForm.isMasterView);
  const nameList = useSelector((state) => state.workPermitForm.nameList);

  // Dispatch actions instead of passing handlers as props
  const handleMasterViewChange = (value) => {
    dispatch(setIsMasterView(value));
  };

  const handleNameListChange = (newList) => {
    dispatch(setNameList(newList));
  };

  return (
    <div>
      {/* Your form rendering logic */}
    </div>
  );
};

  1. 简化的组件道具: 集成 Redux 后,您可以删除现在通过全局状态处理的大部分 props,只传递真正本地的 props。

WorkPermitForm 的维护方式示例:

const WorkPermitForm = () => {
  const isMasterView = useSelector((state) => state.workPermitForm.isMasterView);
  const typeList = useSelector((state) => state.workPermitForm.typeList);
  // Other state variables...
  
  const dispatch = useDispatch();
  
  const handleInputChange = (e) => {
    // Dispatch an action to update the form input
  };

  return (
    <form>
      {/* Render form fields, passing down only local props */}
    </form>
  );
};

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