构建一个既可以控制也可以不受控制的React组件

时间:2019-06-20 22:27:24

标签: reactjs

我试图弄清受控和非受控反应组件之间的区别,所以我认为我可以建立一个可以是但不能同时是两者的控件。似乎<input>使用的模式是,如果您提供value道具,那么它将受到控制,否则将是不受控制的,并且您可以使用defaultValue道具为默认设置提供默认值。 / p>

我的示例控件是一个简单的数字增量器/减量器,带有用于递增和递减的按钮以及一个显示当前值的标签。

我的问题是。

  1. 我以正确的方式解决了这个问题。
  2. 我编写了许多测试以涵盖我能想到的所有场景,这些场景是否全部有效,我是否错过了任何情况。

我希望通过本示例和任何反馈来全面了解受控与非受控以及何时使用它们。

我的代码和所有测试均在此代码框中https://codesandbox.io/s/kind-archimedes-cs0qy

但是为了方便起见,这里重复了我的内容...

    import React, { useState } from "react";

    export const NumberInput = ({ onChange, value, defaultValue, min, max }) => {
      const [uncontrolledVal, setUncontrolledVal] = useState(
        defaultValue || min || 0
      );

      if (
        (value && (value > max || value < min)) ||
        (defaultValue && (defaultValue > max || defaultValue < min))
      ) {
        throw new Error("Value out of range");
      }

      const handlePlusClick = () => {
        if (value && onChange) {
          onChange(value + 1);
        } else {
          const newValue = uncontrolledVal + 1;
          setUncontrolledVal(newValue);
          if (onChange) {
            onChange(newValue);
          }
        }
      };
      const handleMinusClick = () => {
        if (value && onChange) {
          onChange(value - 1);
        } else {
          const newValue = uncontrolledVal - 1;
          setUncontrolledVal(newValue);
          if (onChange) {
            onChange(newValue);
          }
        }
      };
      return (
        <>
          <button
            data-testid="decrement"
            disabled={value ? value === min : uncontrolledVal === min}
            onClick={() => handleMinusClick()}
          >
            {"-"}
          </button>
          <span className="mx-3 font-weight-bold">{value || uncontrolledVal}</span>
          <button
            data-testid="increment"
            disabled={value ? value === max : uncontrolledVal === max}
            onClick={() => handlePlusClick()}
          >
            {"+"}
          </button>
        </>
      );
    };

1 个答案:

答案 0 :(得分:0)

对于这样的东西,一个自定义的增量器,不存在不受控制的版本。 “不受控制”适用于HTML 5中的内置输入字段,例如文本字段,复选框或文件上传。

受控表示输入的值由状态或prop值设置,并使用自定义功能进行更新。不受控制意味着它会自行处理其值的更改,并且要使用它们时必须手动检索它们的值。

这可以使用类似ref的东西来实现。

如果将输入字段的值绑定到值而不提供提供更新其值onChange的功能,则它将不会响应任何用户输入。但是,您可以为其提供defaultValue,它将仍然响应用户输入。

您可以在此处了解更多信息:https://reactjs.org/docs/uncontrolled-components.html

这能回答您的问题吗?