更新react中的表单

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

我有一个使用 devextreme 代码块进行 React 的代码,其中包含多个字段。两个按钮,一个添加新行,一个删除其相应的行。由于我的组件每次更改时都会发送数据,而无需任何按钮,因此我使用 onBlur 来通过双击来更改状态。但我的用户希望它们一键更新。那么有什么方法可以执行此特定操作。 我的代码

import React, { useState, useEffect } from "react";
import apis from "../api-constants";
import './temporarystack.scss';
import DataGrid, { Column } from "devextreme-react/data-grid";
import useGetAPI from "../getAPIS";
import { Button, SelectBox } from "devextreme-react";
import { formatMessage } from "devextreme/localization";

function TemporaryStack({ tokenDetails, operation, isTempUsed, temporaryStacksJSON }) {

  const [showTable, setShowTable] = useState(false);
  const [listData, setListData] = useState([{
    shed: '',
    storageType: '',
    assignedBags: '',
    fcapacity: '',
    maxBags: '',
    lead: '',
    bagsPerLayer: '',
    location: '',
    comment: '',
  }]);
  const [shedOptions, setShedOptions] = useState(null);
  const [threshold, setThreshold] = useState({})
  const storageTypeOptions = [
    { id: 1, name: 'Gangway' },
    { id: 2, name: 'Alleyway' },
    { id: 3, name: 'Road Side' },
    { id: 4, name: 'Plinth' },
    { id: 5, name: 'Other' }
  ]


  useEffect(() => {

    async function Dataapi() {
      const responceforshed = await useGetAPI(apis.GET_GODOWN_UNITS(operation))
    const responceforthreshold = await useGetAPI(apis.GET_BAGWEIGHT_THRESHOLD_MAXIMUXBAGCAPACITY)
      setShedOptions(responceforshed.data)
    setThreshold(responceforthreshold.data)
    }

    if (showTable === true) {
      Dataapi()
    }

  }, [operation, tokenDetails, showTable])
  useEffect(() => {
    temporaryStacksJSON(listData.map(obj=>{
    const {fcapacity,storageType,location,comment,bagsPerLayer,assignedBags,lead,maxBags,shed}=obj
      return {
        fcapacity:fcapacity,
        storageType:storageType,
        location:location,
        comment:comment,
        bagsPerLayer:bagsPerLayer,
        assignedBags:assignedBags,
        flagRecordExists:true,
        isTemporaryStackUsed:true,
        lead:lead,
        maxBags:maxBags,
        mappedGenericId:tokenDetails.genericid,
        mappedGodownUnitId:shed
      }
    }))
  }, [listData])


  // removing data when Temporary stack is unchecked and initialization state
  const handleCheckboxChange = (e) => {
    const isChecked = e.target.checked;
    setShowTable(isChecked);
    isTempUsed(isChecked)
    if (!isChecked) {
      setListData([])
    }
  };

  // adding new row to the temporary stack
  const addRow = () => {
    const newItem = {
      shed: shedOptions && shedOptions.length > 0 ? shedOptions[0]?.value : '',
      storageType: storageTypeOptions.length > 0 ? storageTypeOptions[0].name : '',
      assignedBags: '',
      fcapacity: '',
      maxBags: '',
      lead: '',
      bagsPerLayer: '',
      location: '',
      comment: '',
    };
    setListData((prevList) => [...prevList, newItem]);

  };

  // to delete a temporary stack
  const deleteRow = (index) => {
    const updatedList = [...listData];
    updatedList.splice(index, 1);
    setListData(updatedList);
  };

  const DataRow = (rowInfo) => (
    <>
      <tr className="main-row">
        <td>
          {rowInfo.rowIndex + 1}
        </td>
        <td >
          <SelectBox
            dataSource={shedOptions}
            displayExpr={'value'}
            valueExpr={'id'}
            onValueChange={e => {
              const updatedList = [...listData];
              updatedList[rowInfo.rowIndex].shed = e;
              setListData(updatedList);
            }}
            value={rowInfo.data.shed}
            defaultValue={rowInfo.data.shed}
          />
        </td>
        <td>
          <SelectBox
            dataSource={storageTypeOptions}
            displayExpr="name"
            valueExpr="name"
            onValueChanged={e => {
              const updatedList = [...listData];
              updatedList[rowInfo.rowIndex].storageType = e.value;
              setListData(updatedList);
            }}
            value={rowInfo.data.storageType}
            defaultValue={rowInfo.data.storageType}
          />
        </td>
        <td>
          <input
            type="number"
            defaultValue={rowInfo.data.assignedBags}
            onBlur={(e) => {
              const updatedList = [...listData];
              updatedList[rowInfo.rowIndex].assignedBags = parseInt(e.target.value)
              setListData(updatedList);
            }}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
              }
            }}
          />
        </td>
        <td>
        <input
            type="number"
            defaultValue={rowInfo.data.fcapacity}
            onBlur={(e) => {
              const updatedList = [...listData];
              updatedList[rowInfo.rowIndex].fcapacity = parseInt(e.target.value)
              setListData(updatedList);
            }}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
              }
            }}
          />
        </td>
        <td>
          <input
            type="number"
            defaultValue={rowInfo.data.maxBags}
            onBlur={(e) => {
              const updatedList = [...listData];
              updatedList[rowInfo.rowIndex].maxBags = parseInt(e.target.value)
              setListData(updatedList);
            }}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
              }
            }}
          />
        </td>
        <td>
          <input

            type="number"
            defaultValue={rowInfo.data.lead}
            onBlur={(e) => {
              const updatedList = [...listData];
              updatedList[rowInfo.rowIndex].lead = parseInt(e.target.value)
              setListData(updatedList);
            }}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
              }
            }}
          />
        </td>
        <td>
          <input
            type="number"
            defaultValue={rowInfo.data.bagsPerLayer}
            onBlur={(e) => {
              const updatedList = [...listData];
              updatedList[rowInfo.rowIndex].bagsPerLayer = parseInt(e.target.value)
              setListData(updatedList);
            }}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
              }
            }}
          />
        </td>
        <td>
          <Button
            icon="close"
            onClick={() => deleteRow(rowInfo.rowIndex)}
            style={{
              borderRadius: '10%',
              padding: 0,
              width: '20px',
              height: '20px',
              minWidth: '20px',
              minHeight: '20px',
              lineHeight: '20px',
            }}
          />
        </td>


      </tr>
      <tr>
        <td></td>
        <td colSpan={2}>
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <div>{formatMessage('LocationDescription')}</div>
            <textarea
              defaultValue={rowInfo.data.location}
              maxLength="25"
              onBlur={(e) => {
                const updatedList = [...listData];
                updatedList[rowInfo.rowIndex].location = (e.target.value)
                setListData(updatedList);
              }}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.preventDefault();
                }
              }}
            />
          </div>
        </td>
        <td colSpan={2}>
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <div style={{ marginRight: '10px' }}>{formatMessage('Commentl')}</div>
            <textarea
              defaultValue={rowInfo.data.comment}
              maxLength="250"
              onBlur={(e) => {
                const updatedList = [...listData];
                updatedList[rowInfo.rowIndex].comment = (e.target.value)
                setListData(updatedList);
              }}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.preventDefault();
                }
              }}
            />
          </div>
        </td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>



      </tr>
    </>
  );
  // rendering the table or state change for data
  const renderTable = () => {
    if (!showTable) return null;

    return (
      <>
        <DataGrid dataSource={listData} showBorders={true} dataRowRender={DataRow}>
          <Column width={25} />
          <Column caption={formatMessage("Shed")} />
          <Column caption={formatMessage('StorageType')} />
          <Column dataField="assignedBags" caption={formatMessage("AssignedBagInTemp")} />
          <Column dataField="fcapacity" caption={formatMessage('Capacity')} />
          <Column dataField="maxBags" caption={formatMessage('MaxBags')} />
          <Column dataField="lead" caption={formatMessage("Lead")} />
          <Column dataField="bagsPerLayer" caption={formatMessage('BagsPerLayer')} />
          <Column width={35} />

        </DataGrid>
        <Button
          onClick={addRow}
          icon="plus"
          className="small-button"
          style={{
            borderRadius: '10%',
            marginTop: '5px',
            padding: 0,
            width: '20px',
            height: '20px',
            minWidth: '20px',
            minHeight: '20px',
            lineHeight: '20px',
          }}
        />

      </>
    );
  };

  return (
    <>
      <label>
        <input type="checkbox" onChange={(e) => handleCheckboxChange(e)} />
        {formatMessage('TemporaryStack')}
      </label>
      {renderTable()}
    </>
  );
};

export default React.memo(TemporaryStack)

我曾尝试使用 onChange,但它正在更新每个字符,并且 Changeevent 无效。该表格的另一件事是用复选框括起来。

javascript reactjs devextreme devextreme-react
1个回答
0
投票

要在 React 中使用 DevExtreme 组件实现一键更新,请从使用

onBlur
切换到
onChange
。此调整可确保您的状态在值更改后立即更新,而不仅仅是在元素失去焦点时更新。如果您的更新是资源密集型的,请记住管理和消除快速的状态变化,以保持性能。此策略通过将状态更改直接链接到用户操作而不需要额外的单击来提供响应更快的用户体验。

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