Reactjs React Hooks表单:默认值未按预期工作

Reactjs React Hooks表单:默认值未按预期工作,reactjs,forms,react-hooks,Reactjs,Forms,React Hooks,我正在使用钩子表单根据用户的区域获取文章。它可以随时更改,通过选择输入来更改文章位置 import React, { useState, useEffect } from 'react'; import useForm from 'react-hook-form'; import { getRegions } from '../../services/regions'; import s from './style.module.scss'; function UpdateRegion({ p

我正在使用钩子表单根据用户的区域获取文章。它可以随时更改,通过选择输入来更改文章位置

import React, { useState, useEffect } from 'react';
import useForm from 'react-hook-form';
import { getRegions } from '../../services/regions';
import s from './style.module.scss';

function UpdateRegion({ putRegion, region }) {
  const [regionsList, setRegionsList] = useState(null);
  const [isLoading, setIsLoading] = useState(null);

  const {
    register, handleSubmit, watch, setValue,
  } = useForm({
    defaultValues: {
      id: region !== null && region.id,
    },
  });

  const { id } = watch();
  const onSubmit = (data) => putRegion(regionsList.find((r) => (r.id === data.id)));

  console.log('WATCH', id);
  console.log('userRegionId', region !== null && region.id);

  useEffect(() => {
    register({ name: 'id' });
  }, [register]);

  const regions = async () => {
    try {
      setIsLoading(true);
      const data = await getRegions();
      setRegionsList(data);
      setIsLoading(false);
    } catch (error) {
      setIsLoading(false);
      console.log(error);
    }
  };

  useEffect(() => {
    if (regionsList === null && !isLoading) {
      regions();
    }
  }, []);

  useEffect(() => {
    if (region !== null) {
      setValue('id', region.id || '');
    }
  }, [region]);

  return (
    <form className={s.container}>
      <select
        name="id"
        ref={register}
        onChange={handleSubmit(onSubmit)}
        className={s.container__select}
      >
        {regionsList !== null && (
          regionsList.map((region) => (
            <option
              value={region.id}
              key={region.id}
              className={s.container__select__option}
            >
              {region.name}
            </option>
          ))
        )}
      </select>
    </form>
  );
}

export default UpdateRegion;

我认为您对
defaultValue
属性的看法是错误的。让我们试着解释一下原因。首先,当钩子第一次调用时,从外部传递的默认值将在以后使用,并且不再更改。因此,使用
useffect
可以观察并更新组件中的实际区域id

import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Loading from 'Components/Loading';
import classNames from 'classnames';
import { getRegions } from '../../services/regions';
import s from './style.module.scss';

function UpdateRegion({ putRegion, region, className }) {
  const [regionsList, setRegionsList] = useState(null);
  const [isLoading, setIsLoading] = useState(null);

  const regions = async () => {
    try {
      setIsLoading(true);
      const data = await getRegions();
      setRegionsList(data);
      setIsLoading(false);
    } catch (error) {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    if (regionsList === null && !isLoading) {
      regions();
    }
  }, []); // eslint-disable-line

  function changeRegion(e) {
    putRegion(regionsList.find((r) => (r.id === e.target.value)));
  }

  if (region !== null) {
    return (
      <form className={classNames(s.container, className)}>
        <select
          name="id"
          onChange={(e) => changeRegion(e)}
          className={s.container__select}
          value={region !== null && region.id}
        >
          {regionsList !== null && (
            regionsList.map((r) => (
              <option
                value={r.id}
                key={r.id}
                className={s.container__select__option}
              >
                {r.name}
              </option>
            ))
          )}
        </select>
      </form>
    );
  } return <Loading small />;
}

UpdateRegion.propTypes = {
  putRegion: PropTypes.func.isRequired,
  region: PropTypes.object.isRequired,
  className: PropTypes.string,
};

UpdateRegion.defaultProps = {
  className: '',
};

export default UpdateRegion;