首页 > 解决方案 > 从材质 ui 映射 html 元素并通过地图渲染的最佳方式

问题描述

            <FormControlLabel
                control={
                    <Switch
                        onChange={(e) => changeSwitchState(e.target.name, e.target.checked)}
                        color='primary'
                        name='a'
                    />
                }
                label="A"
            />
            <FormControlLabel
                control={
                    <Switch
                        onChange={(e) => changeSwitchState(e.target.name, e.target.checked)}
                        color='primary'
                        name='b'
                    />
                }
                label="B"
            />
            <FormControlLabel
                control={
                    <Switch
                        onChange={(e) => changeSwitchState(e.target.name, e.target.checked)}
                        color='primary'
                        name='c'
                    />
                } label="C" />
            <span>D</span>
            <InputText
                className={inputValidation(inputValues.e, inputValues.f, inputValues.d) ? 'err' : 'validated'}
                id='d'
                keyfilter="num"
                value={inputValues.d}
                onChange={e => changeInputValue(e.target.id, e.target.value)}
            />
            <span>E</span>
            <InputText
                className={inputValidation(inputValues.f, inputValues.d, inputValues.e) ? 'errE' : 'validateE'}
                id='e'
                value={inputValues.e}
                onChange={e => changeInputValue(e.target.id, e.target.value)}
                mode="decimal"
                useGrouping={false}
            />
    )
};

这是我的代码我想让代码更短并通过地图方式呈现这个输入和切换按钮有人可以解释如何做到这一点以及最佳实践是什么以及如何不丢失我通过道具方式接收的数据?

标签: htmlreactjs

解决方案


最好的方法是为此设置配置数组。理想情况下,您希望在 React 中将输入保持在“受控状态”,以便您的用户界面始终代表您的状态。

让我们首先配置一个常量,它包含您的 formControlLabels 的初始配置,它包含我可以从您提供的代码中读取的信息。

它可能看起来像这样,并且可以在使用它的组件之外定义。为每个输入保存对象的数组是理想的,因为稍后我们想map在您的返回方法中使用这些对象来呈现它们。

const formControlLabelConfig = [
  {
    color: "primary",
    name: "a",
    label: "A",
    state: false
  },
  {
    color: "primary",
    name: "b",
    label: "B",
    state: false
  },
  {
    color: "primary",
    name: "c",
    label: "C",
    state: false
  }
];

类似于您的 textInput 组件

const textInputConfig = [
  {
    keyFilter: "num",
    id: "d",
    mode: undefined,
    className: "err",
    errorClassName: "validated",
    useGrouping: undefined,
    value: ""
  },
  {
    keyFilter: "num",
    id: "e",
    mode: "decimal",
    className: "errE",
    errorClassName: "validateE",
    useGrouping: false,
    value: ""
  }
];

我们可以使用此初始配置设置状态变量。这将在您用于呈现FormControlLabel和的功能组件内InputText components

const [formControlLabelState, setFormControlLabelState] = useState(formControlLabelConfig);
const [textInputConfig, setTextInputConfig] = useState(textInputConfig);

然后我们可以使用 map 根据其配置来渲染每个组件。我已经模拟了一些你最终会得到的东西

import React, { useState } from "react";

const formControlLabelConfig = [
  {
    color: "primary",
    name: "a",
    label: "A",
    state: false
  },
  {
    color: "primary",
    name: "b",
    label: "B",
    state: false
  },
  {
    color: "primary",
    name: "c",
    label: "C",
    state: false
  }
];

const textInputConfig = [
  {
    keyFilter: "num",
    id: "d",
    mode: undefined,
    className: "err",
    errorClassName: "validated",
    useGrouping: undefined,
    value: ""
  },
  {
    keyFilter: "num",
    id: "e",
    mode: "decimal",
    className: "errE",
    errorClassName: "validateE",
    useGrouping: false,
    value: ""
  }
];

const SomeComponentName = () => {
  
  const [formControlLabelState, setFormControlLabelState] = useState(
    formControlLabelConfig
  );
  const [textInputState, setTextInputState] = useState(textInputConfig);

  const getInputClassName = () => {
    let className = "";
    //return the className on validation
    return className;
  };

  const changeInputValue = (id, value) => {
    setTextInputState((prevState) => {
      const newState = [...prevState];
      const index = newState.findIndex((config) => config.id === id);
      newState[index].value = value;
      return newState;
    });
  };

  const changeSwitchState = (name, chackedState) => {
    setFormControlLabelState((prevState) => {
      const newState = [...prevState];
      const index = newState.findIndex((config) => config.name === name);
      newState[index].state = chackedState;
      return newState;
    });
  };

  return (
    <>
      {formControlLabelState.map((config) => (
        <FormControlLabel
          key={config.id}
          control={
            <Switch
              onChange={(e) =>
                changeSwitchState(e.target.name, e.target.checked)
              }
              color={config.color}
              name={config.name}
              value={config.checked} //would need to check this. Not sure what attribute is used to set the checked state
            />
          }
          label="B"
        />
      ))}
      <span>D</span>
      {textInputState.map((config) => (
        <InputText
          key={config.id}
          className={() => getInputClassName(config.id)}
          id={config.id}
          value={config.value}
          onChange={(e) => changeInputValue(e.target.id, e.target.value)}
          mode={config.mode}
          useGrouping={config.useGrouping}
        />
      ))}
    </>
  );
};

推荐阅读