【问题标题】:How to set react state to some initial state based on the value of formfield using react and typescript?如何使用反应和打字稿根据表单字段的值将反应状态设置为一些初始状态?
【发布时间】:2021-01-28 23:55:19
【问题描述】:

我想根据某些条件使用 react 将状态设置为初始状态。

我想做什么?

我有一个名为 active 的复选框。如果用户检查活动字段,则名为活动的表单字段应设置为基于选择菜单中选择的选项的值。

基本上是这样的,

如上图所示,检查字段将具有名为“活动”的表单字段。 如果未选中,则选择菜单不可见,名称为 active 的表单字段将设置为值“none”。

如果选中,则选择菜单可见,如果 type2 值,则名称为 active 的表单字段将设置为“type2”,如果从菜单中选择 type1 选项,则将其设置为“type1”。

下面是我的代码,

const Parent = () => { 
    const [isChecked, setIsChecked] = React.useState(false);
    return (
        <Switch
            checked={isChecked}
            disabled={mode === 'edit'}
            onChange=(() => {
                if (isChecked) {
                    setIsChecked(false);
                    form.setFieldValue('active', 'none');
                } else {
                    setIsChecked(true);
                }
            }
        />
    );
}


    
const Child = () => {
    
    const handleOnchange = (selectedType, form) => {
        if (selectedType === 'type1') {
            form.setFieldValue('active', 'type1');
        } else if (selectedType === 'type2') {
            form.setFieldValue('active', 'type2');
        } else {
            //do nothing
        }
    }
    const typeOptions = () => {
        label: 'type1', name:'type1',
        label: 'type2', name: 'type2',
    }
    return ( 
        <FormField fieldId="type">
            {({ field, form }: FieldProps) => (
                <Select 
                    options={typeOptions}
                    onChange=(()=> handleOnChange(type,form));
                    placeholder="select"
                    value=value={typeOptions.filter(option => option.value === 
                        field.value)}
                 /> 
             ))}
         </FormField>
     );
 }

上面的代码有效。但在创建和编辑模式中使用相同的父组件。在编辑模式下,如果活动字段值在创建模式下是 type1 或 type2,我希望检查活动字段。如果在创建模式下活动字段值设置为无,则取消选中。

基本上在编辑模式下,我想检索活动字段的值。因为我在开关组件检查属性上使用 isChecked 状态,并且当组件卸载时,它将设置为 false,因此即使在创建模式下检查了活动字段,也不会在编辑模式下检查活动字段。

我尝试过类似下面的方法,

const Parent = () => {
    const active = formikBag.values('active');
    const checked = active === 'type1' || 'type2';
    const [isChecked, setIsChecked] = React.useState(checked);
    return(
        <Switch
            disabled={mode === edit}
            checked={isChecked} // true | active is not assigned to boolean | 
            //undefined
            onChange = (() => {
                setIsChecked={false} // false is not assignable to 
                //setStateAction(true | active)
            } 
        />
    );
}

但我收到类似的错误 真实 | active 未分配给 boolean |不明确的 false 不能分配给 setStateAction(true | active)

不确定是什么原因造成的。有人可以帮我解决这个问题。谢谢。

或者换句话说,如果在下面的语句中活动变量是“type1”或“type2”,我如何将检查变量设置为true

const checked = active === 'type1' || active === 'type2'

【问题讨论】:

  • 在第二个Parent,尝试:Reacte.useState(!!checked)
  • setIsChecked 是一个函数,所以你会做setIsChecked(false) 而不是setIsChecked={false}
  • 这些代码 sn-ps 缺少一些东西,我不知道它是在复制和粘贴中丢失了,还是在您的代码中损坏了。您有未定义的变量 modeformikBagformikBag 我们可以从钩子中获得。 mode 来自哪里?是formik状态还是来自props
  • 另外,看起来组件是兄弟姐妹。不是父母和孩子。

标签: javascript reactjs typescript


【解决方案1】:

有很多方法可以设置它,但这就是我所做的。

我们将在表单中包含三个字段:

  1. mode:“查看”或“编辑”
  2. checked: truefalse
  3. active:“type1”、“type2”或“none”
type ValidTypes = "type1" | "type2" | "none";

interface FormState {
  mode: "view" | "edit";
  checked: boolean;
  active: ValidTypes;
}

我们需要的一切都依赖于表单状态,所以没有更多的useState。一切都可以从表单状态访问。

formik 带有一个内置的帮助函数handleChange,我们可以使用它,只要元素的“name”属性设置为字段的名称。我们希望在checked 字段上进行额外的事件处理,因为我们想在未选中复选框时清除active 的值并将其设置为none。所以我们打电话给handleChange,但我们也可以打电话给setFieldValue

我正在使用来自material-uiCheckbox 组件,下拉列表只是常规的select 元素。材料版本有问题。

RenderForm 组件获取form 的所有属性为props。我使用的是valueshandleChangesetFieldValue

const RenderForm = ({ values, handleChange, setFieldValue }: FormikProps<FormState>) => {
  
  // for development purposes, log the state of `active`
  console.log("active: " + values.active);

  // show options if in edit mode or if checked is true
  const isShowOptions = values.mode === "edit" || values.checked;

  return (
    <Form>
      <div>
        {"Mode: "}
        <select name="mode" value={values.mode} onChange={handleChange}>
          <option value="view">View</option>
          <option value="edit">Edit</option>
        </select>
      </div>
      <div>
        <Checkbox
          name="checked"
          value={values.checked}
          onChange={(event, isChecked) => {
            // want to handle change for this field, but also want to
            // set `active` to `none` when unchecking
            handleChange(event);
            if (!isChecked) {
              setFieldValue("active", "none");
            }
          }}
        />
        {isShowOptions && ( // render this field conditionally
          <select name="active" value={values.active} onChange={handleChange}>
            <option value="none">Select</option>
            <option value="type1">Type 1</option>
            <option value="type2">Type 2</option>
          </select>
        )}
      </div>
      <div>
        <button type="submit">Submit</button>
      </div>
    </Form>
  );
};

const MyForm = () => {
  return (
    <Formik
      initialValues={{ mode: "view", active: "none", checked: false }}
      onSubmit={console.log}
      component={RenderForm}
    />
  );
};

export default MyForm;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 2020-05-29
    • 2023-03-24
    • 2016-08-13
    • 2021-12-21
    • 1970-01-01
    • 2021-08-30
    相关资源
    最近更新 更多