首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何更新使用自定义钩子的变量的状态值

如何更新使用自定义钩子的变量的状态值
EN

Stack Overflow用户
提问于 2019-06-02 16:49:22
回答 1查看 4.9K关注 0票数 1

我的组件有表单输入字段。它们使用了一个带有它们的值和每个输入字段的setValue的useState挂钩。我想优化我的组件,以便输入字段使用相同的自定义钩子,我称之为useFormInput

受丹·阿布拉莫夫的启发,https://youtu.be/dpw9EHDh2bM在49:42

这个可以完美地工作。但是,现在我希望在创建新练习后更新用户名。这是在onSubmit方法中。但我不确定该怎么做。在重构之前,我可以使用setUserName(),但是现在用户名是由通用的自定义钩子函数useFormInput设置的

用户名有一个onChange方法,所以我想我可以使用这个方法。但是,这里使用e.target.value,因为它用于输入字段。

组件:我注释掉了setUserName(''),这里我想更新用户名

代码语言:javascript
复制
  const CreateExercise = () => {
  const inputEl = useRef(null)
  const username = useFormInput('')
  const description = useFormInput('')
  const duration = useFormInput(0)
  const date = useFormInput(new Date())
  const [users, setUsers] = useState([])
  useEffect(() => {
    axios
      .get('http://localhost:5000/users/')
      .then(res => {
        if (res.data.length > 0) {
          setUsers(res.data.map(user => user.username))
        }
      })
      .catch(err => console.log(err))
  }, [])
  const onSubmit = e => {
    e.preventDefault()
    const exercise = {
      username: username.value,
      description: description.value,
      duration: duration.value,
      date: date.value
    }
    axios
      .post('http://localhost:5000/exercises/add', exercise)
      .then(res => console.log(res.data))
      debugger
    // setUsername('')
    window.location = '/'
  }

自定义挂钩useFormInput:

代码语言:javascript
复制
const useFormInput = initialValue => {
  const [value, setValue] = useState(initialValue)
  const handleChange = e => {
    const newValue = e.target ? e.target.value : e
    setValue(newValue)
  }
  return {
    value,
    onChange: handleChange
  }
}

我希望username状态下的值更新为空字符串‘’

完整的代码在我的https://github.com/jeltehomminga/mern-tracker上的repo上

EN

回答 1

Stack Overflow用户

发布于 2019-06-03 02:28:27

我看了一下,做了一个带验证的PR - Formik实现。

这是PR - https://github.com/jeltehomminga/mern-tracker/pull/1

UI视图

代码语言:javascript
复制
<>
  <h3>Create New Exercise Log</h3>

  <pre>{JSON.stringify({ formData }, null, 2)}</pre>

  <ExerciseForm {...{ users }} onChange={data => setFormData(data)} />
</>

CreateExercise表单

代码语言:javascript
复制
import React from "react";

import * as Yup from "yup";
import { Formik, Form, Field } from "formik";

import DatePicker from "react-datepicker";
import cx from "classnames";

const requiredMessage = "Required";

const exerciseFormSchema = Yup.object().shape({
  username: Yup.string().required(requiredMessage),
  description: Yup.string()
    .min(2, "Too Short!")
    .required(requiredMessage),
  duration: Yup.number()
    .integer()
    .min(1, "Min minutes!")
    .max(60, "Max minutes!")
    .required(requiredMessage),
  date: Yup.string().required(requiredMessage)
});

const ExerciseForm = ({ users = [], onChange }) => {
  return (
    <Formik
      initialValues={{
        username: "",
        description: "",
        duration: "",
        date: ""
      }}
      validationSchema={exerciseFormSchema}
      onSubmit={values => onChange(values)}
    >
      {({
        values,
        touched,
        errors,
        handleChange,
        handleBlur,
        isSubmitting,
        setFieldValue
      }) => {
        const getProps = name => ({
          name,
          value: values[name],
          onChange: handleChange,
          onBlur: handleBlur,
          className: cx("form-control", {
            "is-invalid": errors[name]
          })
        });

        return isSubmitting ? (
          // Replace this with whatever you want...
          <p>Thanks for the Exercise!</p>
        ) : (
          <Form>
            <FormControl label="Username">
              <>
                <select {...getProps("username")}>
                  <>
                    <option value="default">Select user...</option>
                    {users.map(person => (
                      <option key={person} value={person.toLowerCase()}>
                        {person}
                      </option>
                    ))}
                  </>
                </select>
                <FormErrorMessage {...{ errors }} name="username" />
              </>
            </FormControl>

            <FormControl label="Description">
              <>
                <Field {...getProps("description")} />
                <FormErrorMessage {...{ errors }} name="description" />
              </>
            </FormControl>

            <FormControl label="Duration in minutes">
              <>
                <Field {...getProps("duration")} type="number" />
                <FormErrorMessage {...{ errors }} name="duration" />
              </>
            </FormControl>

            <FormControl label="Date">
              <>
                {/* Was present before refactor */}
                <div>
                  <DatePicker
                    {...getProps("date")}
                    selected={values.date}
                    minDate={new Date()}
                    onChange={date => setFieldValue("date", date)}
                  />
                  <FormErrorMessage {...{ errors }} name="date" />
                </div>
              </>
            </FormControl>

            <button type="submit" className="btn btn-primary">
              Create Exercise log
            </button>
          </Form>
        );
      }}
    </Formik>
  );
};

export default ExerciseForm;

// Created to manage label and parent className
const FormControl = ({ label, children }) => (
  <div className="form-group">
    <label>{label}:</label>

    {children}
  </div>
);

const FormErrorMessage = ({ name, errors }) => {
  const error = errors && errors[name];

  return error ? (
    <div
      class="invalid-feedback"
      // Add inline style override as error message cannot sit as sibling to datePicker (bootstrap css)
      style={{ display: "block" }}
    >
      {error}
    </div>
  ) : null;
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56413550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档