首页 > 解决方案 > 迭代时在动态列中显示表单

问题描述

我有一个长表格,其中包含混合类型的列。我的意思是某些字段的宽度为 100%,某些字段的宽度约为 33%,这样我就可以在一列中显示 3 个字段,依此类推。我可以在不迭代的情况下做到这一点,但是如果通过迭代显示字段以避免代码重复,如何做到这一点?我也创建了一个沙箱,我没有使用第三方 css 框架,比如 bootstrap,只是一个 flex 或者网格可以工作。

这是我尝试过的方法:

const formFields = [
  { id: 1, name: "first_name", component: TextField, label: "First Name" },
  { id: 1, name: "last_name", component: TextField, label: "Last Name" },
  { id: 1, name: "age", component: TextField, label: "Age" },
  { id: 1, name: "city", component: TextField, label: "City" },
  { id: 1, name: "state", component: TextField, label: "State" },
  { id: 1, name: "country", component: TextField, label: "Country" }
];

const FlexibleForm = () => {
  return (
    <React.Fragment>
      <Form onSubmit={() => console.log("something")}>
        <FlexRow>
          <FlexColumn size={12}>
            {formFields.map(({ id, name, label, component }) => {
              return (
                <Field
                  key={id}
                  name={name}
                  label={label}
                  component={component}
                />
              );
            })}
          </FlexColumn>
        </FlexRow>
        <h2>Another without iteration</h2>
        <FlexRow>
          <FlexColumn size={6}>
            <Field name="first_name" label="First Name" component={TextField} />
          </FlexColumn>
          <FlexColumn size={6}>
            <Field name="last_name" label="Last Name" component={TextField} />
          </FlexColumn>
        </FlexRow>
        <FlexRow>
          <FlexColumn size={12}>
            <Field name="age" label="Age" component={TextField} />
          </FlexColumn>
        </FlexRow>
        <FlexRow>
          <FlexColumn size={4}>
            <Field name="city" label="City" component={TextField} />
          </FlexColumn>
          <FlexColumn size={4}>
            <Field name="state" label="State" component={TextField} />
          </FlexColumn>
          <FlexColumn size={4}>
            <Field name="country" label="Country" component={TextField} />
          </FlexColumn>
        </FlexRow>
      </Form>
    </React.Fragment>
  );
};

export default reduxForm({
  form: "form"
})(FlexibleForm);

export const FlexRow = styled.div`
  display: flex;
  div {
    margin-right: 10px;
  }
`;

export const FlexColumn = styled.div`
  width: ${props => (props.size / 12) * 100}vw;
`;

这是codesandbox链接https://codesandbox.io/s/l7lm1qp0pq

标签: javascriptreactjs

解决方案


这是<FlexRow>组件

const FlexRow = props => {
 return (
   <div style={{ display: "flex" }}>
    {props.elements.map((element, index) => {
       const obj = element.component;
       return (
         <FlexColumn key={index} size={Math.round(12 / props.elements.length)}>
           <Field
             name={element.name}
             label={element.label}
             component={obj[Object.keys(obj)[0]]}
           />
         </FlexColumn>
       );
    })}
  </div>
 );
};

这是<FlexColumn>组件

const FlexColumn = styled.div`
   width: ${props => (props.size / 12) * 100}vw;
   margin-right: 10px;
`;

<FlexibleForm>应该看起来像这样:

const FlexibleForm = () => {
    return (
        <React.Fragment>
          <Form onSubmit={() => console.log("something")}>
            <FlexRow
              elements={[
                { name: "first_name", label: "First Name", component: {TextField} },
                { name: "last_name", label: "Last Name", component: {TextField} }
              ]}
            />
            <FlexRow
              elements={[{ name: "age", label: "Age", component: {TextField} }]}
            />
            <FlexRow
              elements={[
                { name: "city", label: "City", component: {TextField} },
                { name: "state", label: "State", component: {TextField} },
                { name: "country", label: "Country", component: {TextField} }
              ]}
            />
          </Form>
        </React.Fragment>
      );
    };

该组件<FlexRow>将在他的道具中循环elements,并将创建一个<FlexColumn>具有良好属性的良好尺寸。从字面上看,它确实在作为数组的道具内部循环elements并返回大小(12除以您拥有的行数),如果您愿意,可以使用以下简单条件更改此值:

element.size ? element.size : Math.round(12 / props.elements.length)并在您的数组中 添加一个size元素elements

{ name: "first_name", label: "First Name", size: 6, component: {TextField} }

然后它添加标签和名称。最后它添加您选择的组件,在这个例子中它是<TextField>

这将避免您重复您的代码。这是向您展示示例的CodeSandBox

希望我确实帮助了你。


推荐阅读