当前位置: 首页 > 知识库问答 >
问题:

带条件反应挂钩的可选受控/非受控反应组件

容宏逸
2023-03-14

在我看来,React-Hooks-useState非常适合模式选择使用props中的值或使用自己的状态,但是当我有条件地使用hook时,lint显示了一些错误。

工作示例

我尝试使用钩子,条件如下,但是使用eslint errorReact钩子useState被有条件地调用。根据doc的解释,React依赖于钩子的调用顺序。

const Counter = ({ value, onChange, defaultValue = 0 }) => {
  const [count, onCountChange] =
    typeof value === "undefined" ? useState(defaultValue) : [value, onChange];
  return (
    <div>
      {count.toString()}
      <button
        onClick={() => {
          onCountChange(count + 1);
        }}
      >
        +
      </button>
    </div>
  );
};
function App() {
  const [count, onCountChange] = useState(0);
  return (
    <div className="App">
      <div>
        Uncontrolled Counter
        <Counter />
      </div>
      <div>
        Controlled Counter
        <Counter value={count} onChange={onCountChange} />
      </div>
    </div>
  );
}

如何使用钩子实现与下面类组件相同的功能?

class CounterClass extends React.Component {
  state = {
    value: this.props.defaultValue || 0
  };
  render() {
    const isControlled = typeof this.props.defaultValue === "undefined";
    const count = isControlled ? this.props.value : this.state.value;

    return (
      <div>
        {count.toString()}
        <button
          onClick={() => {
            isControlled &&
              this.props.onChange &&
              this.props.onChange(this.props.value + 1);
            !isControlled && this.setState({ value: this.state.value + 1 });
          }}
        >
          +
        </button>
      </div>
    );
  }
}

或者这种道具/状态可选的方式在一个组件中是错误的?

我从React JSX


共有2个答案

曾实
2023-03-14

好问题!我认为这可以通过钩子来解决,方法是使useState调用成为无条件的,并且只使部分成为有条件的,在这里您可以决定渲染哪个状态以及使用什么更改处理程序。

我刚刚发布了一个钩子,它解决了这个问题:使用可选的受控状态

用法:

import useOptionallyControlledState from 'use-optionally-controlled-state';
 
function Expander({
  expanded: controlledExpanded,
  initialExpanded = false,
  onChange
}) {
  const [expanded, setExpanded] = useOptionallyControlledState({
    controlledValue: controlledExpanded,
    initialValue: initialExpanded,
    onChange
  });
 
  function onToggle() {
    setExpanded(!expanded);
  }
 
  return (
    <>
      <button onClick={onToggle} type="button">
        Toggle
      </button>
      {expanded && <div>{children}</div>}
    </>
  );
}

// Usage of the component:

// Controlled
<Expander expanded={expanded} onChange={onExpandedChange} />
 
// Uncontrolled using the default value for the `initialExpanded` prop
<Expander />
 
// Uncontrolled, but with a change handler if the owner wants to be notified
<Expander initialExpanded onChange={onExpandedChange} />

通过使用钩子来实现这一点,您不必将额外的组件包装起来,理论上您可以将其应用于同一组件中的多个道具(例如

丘华翰
2023-03-14

您可以将组件分为完全受控和完全不受控。演示

const CounterRepresentation = ({ value, onChange }) => (
  <div>
    {value.toString()}
    <button
      onClick={() => {
        onChange(value + 1);
      }}
    >
      +
    </button>
  </div>
);

const Uncontrolled = ({ defaultValue = 0 }) => {
  const [value, onChange] = useState(defaultValue);
  return <CounterRepresentation value={value} onChange={onChange} />;
};

// Either use representation directly or uncontrolled
const Counter = ({ value, onChange, defaultValue = 0 }) => {
  return typeof value === "undefined" ? (
    <Uncontrolled defaultValue={defaultValue} />
  ) : (
    <CounterRepresentation value={value} onChange={onChange} />
  );
};
 类似资料:
  • 问题内容: 几乎在每个ReactJS教程中,甚至在用于处理输入更改的官方文档中,都建议使用onChange。我们使用状态作为值,并通过onChange对其进行更改。这会在每个按键中触发渲染。所以, 渲染真的那么便宜吗? 输入值不保存在DOM中吗?因此DOM和VirtualDOM之间没有区别,因此尽管渲染发生了什么变化?(可能是错误的假设)。 出于娱乐和学习目的,我尝试了以下方法: 使用自定义函数和

  • 对于文本类型的输入很容易,使用onChange()我更新状态,调用setState(),并通过其value属性显示输入上的状态。然而,对于复选框,甚至更多的文件,我完全迷路了。 这将是: 处理程序 事件对象的属性 属性。。。输入 输入示例 onChange()

  • 问题内容: ReactJS中什么是受控组件和非受控组件?它们之间有何不同? 问题答案: 这与有状态DOM组件(表单元素)有关,而React文档解释了区别: 甲控制的部件是一个,通过取其电流值和通过像回调通知变化。父组件通过处理回调并管理其自身的状态并将新值作为道具传递给受控组件来“控制”它。您也可以将其称为“哑组件”。 一个不受控制的组件是一个存储其自己的内部状态,并且您使用查询DOM ,当你需要

  • 问题内容: 我是React的新手,可能缺少正确的术语来找到我的问题的解决方案。没那么难。 我正在构建一个简单的应用程序,它显示一组问题,一次显示一个问题。回答一个问题后,显示下一个问题。 我有一个呈现3个复选框的组件,每个复选框代表一个可能的问题。 在我的主要组件内部,我这样调用该组件: 是我的函数,该函数递增以显示下一个问题: 一切正常,除了:当显示下一个问题时,我希望所有3个复选框都不再选中。

  • 本文向大家介绍受控组件和非受控组件有什么区别?相关面试题,主要包含被问及受控组件和非受控组件有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 受控组件用value和组件的state绑定,当value更新时,会自动更新state 非受控组件没有value,采用ref直接操作dom