react-hook-form 一个表单联动的例子

1,264 阅读1分钟

翻了下官方文档没找到相关例子,自己写了一个,功能很简单,就是选择不同的国家展示不同的城市,另外也可以重新设置默认城市。

const map = {
  china: ['Shanghai', 'Beijing', 'Hongkong'],
  usa: ['New York', 'Washington', 'huston'],
  korea: ['seoul'],
};

const Form = () => {
  const {
    register,
    handleSubmit,
    watch,
    setValue,
    formState: { errors },
  } = useForm({
    mode: 'onChange',
    defaultValues: {
      username: '',
      password: '',
      country: 'china',
      city: 'Shanghai',
    },
  });

  const onSubmit = (values) => {
    console.log('values:', values);
  };

  const onError = (err) => {
    console.log('errors:', err);
  };

  const country = watch('country');

  // 如果选中了usa,将默认城市设置为huston
  useEffect(() => {
    if (country === 'usa') {
      setValue('city', 'huston');
    }
  }, [country]);

  return (
    <div style={{ padding: 40 }}>
      <form onSubmit={handleSubmit(onSubmit, onError)}>
        <fieldset>
          <legend>user profile </legend>
          <label>username:</label>
          <input {...register('username', { required: true })} />
          {errors.username?.type === 'required' && (
            <p style={{ color: 'red' }}>username is required</p>
          )}
          <br />
          <label>password:</label>
          <input {...register('password', { required: true, minLength: 6 })} />
          <br />
          <label>country:</label>
          <select {...register('country', { required: true })}>
            <option value="china">china</option>
            <option value="usa">usa</option>
            <option value="korea">korea</option>
          </select>
          <br />
          <label>city:</label>
          <select {...register('city', { required: true })}>
            {map[country].map((el, idx) => {
              return (
                <option key={idx} value={el}>
                  {el}
                </option>
              );
            })}
          </select>
          <br />
          <input type="submit" />
        </fieldset>
      </form>
    </div>
  );
};