【问题标题】:How properly connect react-final-form and material-ui-chip-input?如何正确连接 react-final-form 和 material-ui-chip-input?
【发布时间】:2021-02-05 15:03:59
【问题描述】:

我正在使用用 Field react-final-form 包装的 material-ui-chip-input。

我只想将“CHIPS”限制为 5 个。

芯片是表示输入、属性或 行动。

material ui docs

如您所见,我在这里使用了 2 个状态

  1. 反应使用状态
  2. react-final-form 内部状态

这是多余的,因为 react-final-form 在内部处理了状态,但我无法正常工作我只是展示了我到目前为止所做的事情。

基本上有 我的实现有两个问题。

  1. 它不会限制我的筹码。
  2. 我的 react-final-form 字段值 - 单击 DeleteChip 时不更新
import ChipInput from 'material-ui-chip-input'
import { Field } from 'react-final-form'

const [state, setState] = useState([])

const AddChip = useCallback(
    (chip) => {
        if (state.length + 1 <= 5) {
        setState((prev) => ([...prev.tags, chip]))
        }
    },
    [setState, state.length]
)

const DeleteChip = useCallback(
    (chip) => {
        setState((prev) => (...prev.state.filter((p) => p !== chip)]
        }))
    },
    [setState]
)

  return (
    <Field name="states" validate={isRequired} >
          {({ input: { value, onChange, ...rest }, meta }) => {
     <ChipInput
        defaultValue={Array.isArray(value) ? value : []} // check value first because material-ui-chip-input require an array, by default react-final-form value is empty string
        onChange={(event) => {  // uncontrolled 
            AddChip(event)
            onChange(event)
            // I tried below code but same result not working
            // if (state.length + 1 <= 5) {
            //  onChange(event)
            // }
        }}
        onDelete={DeleteChip} 
       />
      }}
    </Field>
  )

material-ui-chip-input

react-final-form

see codesandbox demo

【问题讨论】:

标签: javascript material-ui react-final-form


【解决方案1】:

这是我的看法: https://codesandbox.io/s/proud-water-xp2y1?file=/src/App.js

关键点:

  • 不要复制状态,让 react final 表单为你处理状态
  • 将空数组作为初始状态传递给 FORM,不要将 defaultValues 传递给 Field。
  • 根据material-ui-chip-input 包,如果在受控模式下使用,您需要使用onAdd,因为我们让反应最终形式处理状态。
  • value 属性添加到 Chipinput。
  • 出于美观原因:实际上不要在 &lt;Form /&gt; 中使用 render-prop - 而是使用功能性子组件。

代码:

import ChipInput from "material-ui-chip-input";
import { Form, Field } from "react-final-form";

export default function App() {
  return (
    <Form
      initialValues={{
        states: []
      }}
      onSubmit={() => console.log("submitted")}
    >
      {({ values, onSubmit }) => (
        <form onSubmit={onSubmit}>
          <Field name="states">
            {({ input: { value, onChange } }) => (
              <ChipInput
                value={value}
                alwaysShowPlaceholder={true}
                placeholder="type states here"
                onAdd={(newVal) => {
                  if (value.length >= 5) return;
                  const newArr = [...value, newVal];
                  onChange(newArr);
                }}
                onDelete={(deletedVal) => {
                  const newArr = value.filter((state) => state !== deletedVal);
                  onChange(newArr);
                }}
              />
            )}
          </Field>
          <p>react useStates</p>

          <p>react-final-form values</p>
          <pre
            style={{
              backgroundColor: "rgba(0,0,0,0.1)",
              padding: "20px"
            }}
          >
            {JSON.stringify(values, 0, 2)}
          </pre>
        </form>
      )}
    </Form>
  );
}

【讨论】:

  • 是的,这是正确的,不需要使用 useState,因为 react-final-form 在内部处理状态。您的演示很棒,我的问题是我不想将 intialValue 放在
    上。我在 上添加了 defaultValue,得到了无限循环。
  • 这是我的工作。从 道具中删除 defaultValue 然后我的值是 value={isEmpty(value) ? [] : 值}
  • 您为什么不想在表单上显示?这就是它的预期用途
  • 我正在处理向导样式的表单,就像 react-final-form 的演示中一样,但在 materia-ul 步进器实现中。我有多个屏幕,每个屏幕 react-final-form 都保存了每个字段的值,但是在移动下一页时,值消失了。所以是的,这就是为什么我没有在
    本身中初始化默认值。
  • 我认为这篇文章对initialValues is resetting issue有帮助
猜你喜欢
  • 2021-01-27
  • 2019-07-15
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 2019-11-18
  • 2019-06-14
  • 2023-03-05
  • 2020-11-03
相关资源
最近更新 更多