反应自定义复选框输入组件不重新渲染

React custom checkbox input component not rerendering

我正在提取我的复选框输入以分离自定义组件,以便以后可以轻松地重用它。但是只要父级的状态发生变化,这个自定义组件内的检查值就不会改变。当我先移动页面然后再打开它时,它实际上在变化,但不是实时的。但是当我使用默认输入组件时,它是实时工作的。知道这怎么可能吗?

import React from 'react';

const Checkbox = ({ name, id, className, onValueChange, defaultChecked = false }) => {
  let classes = 'checkbox';

  if (className) {
    classes += ` ${className}`;
  }

  const valueChangeHandler = (event) => {
    if (onValueChange) {
      onValueChange(event.target.checked);
    }
  };

  return (
    <input 
      type="checkbox"
      name={ name }
      id={ id }
      className={ classes }
      defaultChecked={ defaultChecked }
      onChange={ valueChangeHandler }
    />
  );
};

export default Checkbox;

我建议阅读 controlled components and, more applicable to your code, uncontrolled components 附近的 React 文档。

理想情况下,您希望使用受控组件,通常由 valueonValueChanged 道具或类似道具组成:

const Checkbox = ({ name, id, className, value, onValueChange }) => {
  const valueChangeHandler = (event) => {
    if (onValueChange) onValueChange(event.target.checked);
  };

  return (
    <input
      type="checkbox"
      name={name}
      id={id}
      checked={!!value}
      className={className ? `checkbox ${className}` : 'checkbox'}
      onChange={valueChangeHandler}
    />
  );
};

然后你会像这样使用它:

function SomeComponent() {
    const defaultValue = true;
    const [checked, setChecked] = React.useState(defaultValue);

    return <div>
        <Checkbox
            value={checked}
            onValueChange={setChecked}
            ...
        />
    </div>;
}

基本上,如果您希望从父级更改复选框的值,您需要一个受控组件,您可以在其中告诉您的复选框它应该是什么值。这里我们简单地用 React.useState 跟踪值,它可以方便地接受默认值。您可以将 useState 替换为例如取而代之的是基于 redux 的 getter/setter。

输入'defaultChecked'只是第一次设置(加载时),所以值改变时不会改变。 您应该将新值传递给 'checked' 属性, 所以试试这个:

import React from 'react';

const Checkbox = ({ name, id, className, onValueChange, defaultChecked = false }) => {
  let classes = 'checkbox';

  if (className) {
    classes += ` ${className}`;
  }

  const valueChangeHandler = (event) => {
    if (onValueChange) {
      onValueChange(event.target.checked);
    }
  };

  return (
    <input 
      type="checkbox"
      name={ name }
      id={ id }
      className={ classes }
      defaultChecked={ defaultChecked }
      checked={defaultChecked}
      onChange={ valueChangeHandler }
    />
  );
};

export default Checkbox;