为什么我无法在ReactJ中连续键入输入字段



我有一个看起来像这样的输入组件:

import React from 'react';
import { PropTypes } from 'prop-types';
const NewCartonInput =
({
  value,
  itemId,
  onChange,
}) => (
  <input
    id={itemId}
    onChange={onChange}
    type="number"
    value={value}
  />
);
NewCartonInput.propTypes = {
  value: PropTypes.number.isRequired,
  itemId: PropTypes.string.isRequired,
  onChange: PropTypes.func.isRequired,
};
export default NewCartonInput;

它位于此父组件中:

import React from 'react';
import { PropTypes } from 'prop-types';
import { sumBy, isEmpty, isEqual, toNumber } from 'lodash';
import T from 'i18n-react';
import uuidv1 from 'uuid/v1';
import { formatNumber } from 'utils/currencyAndNumberFormatting';
import Container from 'components/Container';
import Content from 'components/Content';
import Header from 'components/Header';
import SearchBox from 'components/SearchBox';
import ListWithHeader from 'components/List/ListWithHeader';
import ListItemWithNumber from 'components/List/ListItemWithNumber';
import Footer from 'components/Footer';
import FooterText from 'components/Footer/Text';
import Prompt from 'components/Prompt';
import TransferPickList from 'components/PrintTemplates/TransferPickList';
import Print from 'components/Print';
import { formatDate } from 'utils/date';
import NewCartonInput from './NewCartonInput';
import { showProgressBar } from './utils';
import './NewTransfer.scss';
export default class NewCarton extends React.Component {
  constructor(props) {
    super(props);
    this.onEditClicked = this.onEditClicked.bind(this);
    this.onClickPrint = this.onClickPrint.bind(this);
    this.onCloseCartonClicked = this.onCloseCartonClicked.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.listCartons = this.listCartons.bind(this);
    this.state = {
      editMode: false,
      showPrintDialog: false,
      disableSearch: false,
    };
  }
  componentWillMount() {
    const {
      onGetCartonItems,
      onClearNewCarton,
      transferRequestId,
      hasChanges,
      routerAction,
    } = this.props;
    if (routerAction === 'PUSH') {
      onClearNewCarton();
    }
    if ((!hasChanges || routerAction === 'PUSH') && transferRequestId) {
      onGetCartonItems(transferRequestId);
    }
  }
  shouldComponentUpdate(newProps) {
    const newItems = newProps.items;
    const oldItems = this.props.items;
    return !isEqual(newItems, oldItems);
  }
  componentWillUnmount() {
    const { onClearShipment } = this.props;
    onClearShipment();
  }
  onEditClicked() {
    this.forceUpdate();
    this.setState({
      editMode: !this.state.editMode,
    });
    this.forceUpdate();
  }
  onClickPrint() {
    this.forceUpdate();
    this.setState({
      showPrintDialog: !this.state.showPrintDialog,
    });
  }
  onCloseCartonClicked(cartonContext) {
    const { onClickClose } = this.props;
    this.setState({
      disableSearch: true,
    });
    onClickClose(cartonContext);
  }
  handleChange(e) {
    const { items, onUpdateQuantity } = this.props;
    const updateItem = items.filter((item) =>
      item.itemId === e.target.id,
    );
    const itemQuantity = toNumber(e.target.value);
    updateItem.total += itemQuantity;
    onUpdateQuantity(e.target.id, itemQuantity);
  }
  listCartons() {
    const {
      items,
      onItemDelete,
      transferRequestId,
    } = this.props;
    const list =
      items.filter((item) => !item.deleted || item.deleted === false);
    return list.map(({
      itemId,
      itemDescription,
      packed,
      total,
    }, index, filteredItems) => {
      let onDeletePress;
      if (deleteMode(filteredItems, this.state.editMode)) {
        onDeletePress = (e) => {
          e.stopPropagation();
          onItemDelete(itemId);
        };
      }
      const packedAll = packed === total && total > 0;
      let countDetailsStr;
      let countDetailsTotal;
      if (transferRequestId) {
        countDetailsStr = (
          <li styleName="newCartonOf">
            of
          </li>
        );
        countDetailsTotal = (
          <li styleName="newCartonTotal">
            {total}
          </li>
        );
      }
      return (
        <li styleName="newCartonQuantity" key={uuidv1()}>
          <ul styleName="newCartonDetails">
            <ListItemWithNumber
              header={itemId}
              section={itemDescription}
              key={itemId}
              onPress={() => {}}
              onDeletePress={onDeletePress}
              checkIcon={packedAll}
              icon={false}
            />
            <ul styleName="newCartonQtyDetails">
              <li styleName="newCartonQtyInput">
                <NewCartonInput
                  value={packed}
                  itemId={itemId}
                  onChange={this.handleChange}
                />
              </li>
              {countDetailsStr}
              {countDetailsTotal}
            </ul>
          </ul>
        </li>
      );
    });
  }
  render() {
    const {
      onSearch,
      items,
      destinationId,
      shipmentId,
      sourceId,
      onClickSave,
      onClickClose,
      shouldNotBlock,
      loading,
      transferRequestId,
      destId,
      hasChanges,
      printRequestedItems,
      currentLocale,
      disableSearch,
    } = this.props;
    const canEditItems = !transferRequestId && !isEmpty(items);
    const backTitle = destId ? T.translate('views.transfers.title.transfers')
      : T.translate('views.transfers.title.transferCartons');
    const itemsPacked = sumBy(
      items, item => item.packed,
    );
    const totalItems = sumBy(
      items, item => item.total,
    );
    const destinationHeader = {
      label: T.translate('views.transfers.labels.destination'),
      value: destinationId,
    };
    let itemsHeader;
    if (transferRequestId) {
      itemsHeader = {
        label: T.translate('views.transfers.labels.items'),
        value: `${formatNumber(itemsPacked)}/${formatNumber(totalItems)}`,
      };
    } else {
      itemsHeader = {
        label: T.translate('views.transfers.labels.items'),
        value: `${formatNumber(itemsPacked)}`,
      };
    }
    const cartonContext = {
      shipmentId,
      transferRequestId,
      sourceId,
      destinationId,
      items: items.filter((item) => !item.deleted || item.deleted === false),
      itemsPacked,
      totalItems,
    };
    let shouldDisableSave = loading || !hasChanges || isEmpty(items);
    let headerAction = () => onClickSave(cartonContext);
    let headerTitle = T.translate('views.transfers.buttons.save');
    const printbtn = T.translate('views.transfers.buttons.print');
    const editbtn = T.translate('views.transfers.buttons.edit');
    const closeCartonbtn = T.translate('views.transfers.buttons.closeCarton');
    let footer;
    if (this.state.editMode) {
      headerAction = this.onEditClicked;
      headerTitle = T.translate('views.transfers.buttons.done');
      shouldDisableSave = loading;
      footer = (
        <FooterText textAlign="center">
          {T.translate('views.transfers.text.instructions')}
        </FooterText>
      );
    } else {
      footer = (
        <Footer
          links={{
            [`${editbtn}`]: {
              onClick: this.onEditClicked,
              hidden: status === 'PACKED',
            },
            [`${printbtn}`]: {
              onClick: () => this.onClickPrint(),
              disabled: loading,
              hidden: !printRequestedItems,
            },
            [`${closeCartonbtn}`]: {
              onClick: () => onClickClose(cartonContext),
              disabled: shouldDisableSave,
            },
          }}
        />
      );
    }
    let printDialog;
    const PickTemplate = (<TransferPickList
      printingDate={formatDate(new Date(), currentLocale)}
      destinationId={destinationId}
      items={cartonContext.items}
    />);
    if (this.state.showPrintDialog) {
      printDialog = (
        <div styleName="printDialog">
          <Print
            templateRef="TransferPickList"
            templates={[PickTemplate]}
            nativePrint
            onClose={this.onClickPrint}
          />
        </div>
      );
    } else {
      printDialog = null;
    }
    return (
      <Container>
        <Header
          title={T.translate('views.transfers.title.newCarton')}
          backTitle={backTitle}
          rightLink={{
            action: headerAction,
            title: headerTitle,
            disabled: shouldDisableSave,
          }}
        />
        <Content>
          {showProgressBar(loading)}
          <Prompt
            onlyOnBack
            shouldNotBlock={shouldNotBlock}
            confirmNavigation={T.translate(
              'views.common.messages.confirmNavigation')}
          />
          <SearchBox
            onSearch={!disableSearch ? onSearch : () => {}}
            placeholder={
              T.translate('shared.components.searchBox.placeholderItemNumber')
            }
            searchButtonText={
              T.translate('shared.components.searchBox.searchButtonText')
            }
            inputDisabled={disableSearch}
          />
          <ListWithHeader
            headerLeft={destinationHeader}
            headerRight={itemsHeader}
          >
            {this.listCartons()}
          </ListWithHeader>
          {printDialog}
        </Content>
        {footer}
      </Container>
    );
  }
}
function deleteMode(filteredItems, editMode) {
  return editMode
    && filteredItems
    && filteredItems.length > 0;
}
NewCarton.propTypes = {
  onClearShipment: PropTypes.func.isRequired,
  onItemDelete: PropTypes.func,
  onSearch: PropTypes.func.isRequired,
  items: PropTypes.arrayOf(PropTypes.shape({
    itemId: PropTypes.string.isRequired,
    itemDescription: PropTypes.string.isRequired,
    packed: PropTypes.number.isRequired,
    total: PropTypes.number.isRequired,
  })),
  onGetCartonItems: PropTypes.func.isRequired,
  onClearNewCarton: PropTypes.func.isRequired,
  hasChanges: PropTypes.bool.isRequired,
  routerAction: PropTypes.string.isRequired,
  transferRequestId: PropTypes.string,
  destId: PropTypes.string,
  sourceId: PropTypes.string.isRequired,
  destinationId: PropTypes.string.isRequired,
  shipmentId: PropTypes.string,
  onClickSave: PropTypes.func.isRequired,
  onClickClose: PropTypes.func.isRequired,
  shouldNotBlock: PropTypes.func.isRequired,
  loading: PropTypes.bool.isRequired,
  printRequestedItems: PropTypes.bool.isRequired,
  currentLocale: PropTypes.string.isRequired,
  disableSearch: PropTypes.bool,
  onUpdateQuantity: PropTypes.func.isRequired,
};
NewCarton.defaultProps = {
  items: [],
  shipmentId: undefined,
  onItemDelete: () => {},
  transferRequestId: undefined,
  destId: undefined,
  disableSearch: false,
};

当我在输入字段中输入一个值一次时,父组件重新呈现,使在输入字段中连续键入的能力失去了功能。我认为它可能必须使用shouldComponentUpdate()做点事,但不确定到底是什么。有什么想法我如何防止这种情况?也许我还需要将shouldComponentUpdate添加到子组件中?

应该取消更新过程。应该使用这来决定是否继续。因此,我认为问题不存在,但是它可能在您执行此操作的oneditClicked((函数上。forceupdate((。也许设置值等于本地状态的受控输入。

相关内容

  • 没有找到相关文章

最新更新