【问题标题】:Unable to toggle state with React hook无法使用 React 钩子切换状态
【发布时间】:2022-01-06 14:12:15
【问题描述】:

我不得不在 JS/React 中将一个类重写为一个函数,但我在让钩子在函数中工作时遇到了一些麻烦。

function Switch(props) {
  const [isActive, setIsActive] = React.useState();
  
  function handleClick() {
    setIsActive(!isActive);
  }
 
  const className = `switch ${props.color} ${props.isActive ? 'on' : 'off'}`;

   return (
      <div className={className}>
        <button className="img" onClick={handleClick} />
        <h3>{props.title}</h3>
      </div>
    );
}

ReactDOM.render((
  <Switch title="Happiness" color="blue" isActive={false} />
), document.querySelector('#root'));

我尝试更改 handleClick 函数(以及其中的 setIsActive),但无法使其工作。提前感谢您的帮助!

注意:没有添加 CSS,因为该部分工作正常。

【问题讨论】:

  • 你当前的 isActive 状态是空的,设置为 false。然后在handleClick函数中这样写 setIsActive(prevState => !prevState)
  • Switch 应该受控制还是不受控制?目前,您通过将相同的值作为 prop 以及内部组件状态传递来混合这两个概念。
  • 一个值应该只有一个来源。决定 isActive 是否应该由这个组件(状态)或组件链中更高级别的东西(道具)管理。如果你把它们混在一起,你迟早会遇到麻烦。

标签: javascript reactjs boolean


【解决方案1】:

您从道具中获取 isActive 而不是从状态中获取。要使其正常工作,您需要进行更改

const [isActive, setIsActive] = React.useState();

const [isActive, setIsActive] = React.useState(props.isActive);

const className = `switch ${props.color} ${props.isActive ? 'on' : 'off'}`;

const className = `switch ${props.color} ${isActive ? 'on' : 'off'}`;

此外,如果您想从外部应用道具更改,您需要添加一个 useEffect 挂钩

useEffect(() => {
  setIsActive(props.isActive)
}, [props.isActive])  

【讨论】:

  • 很抱歉,这是一个非常糟糕的做法。正确的方法是通过 props 传递一个更改 isActive 的函数,以便该值只有一个来源。
  • @marzelin 是的,提升状态会更干净。我只是想展示一种不创建另一个组件的方法。 :)
【解决方案2】:

您还需要查看组件状态 isActive。您可以使用您的道具 isActive 进行逻辑或它(此处仅作为默认值):

  const className = `switch ${props.color} ${
    props.isActive || isActive ? "on" : "off"
  }`;

【讨论】:

    【解决方案3】:

    您正在尝试通过子组件中的状态更改组件接收的道具。道具是(应该)不可变的。如果你想改变组件的行为,

    1. 复制状态变量中的props

      const [isActive, setIsActive] = React.useState(props.isActive);

    2. 使用状态更新的函数形式。在新状态依赖于先前状态的情况下更重要

      function handleClick() { setIsActive(prevState=&gt;!prevState.isActive); }

    3. 更新对状态变量的引用而不是接收到的道具值

    const className = switch ${props.color} ${isActive ? '开' : '关'};

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 2020-05-12
      • 2022-01-22
      • 2020-04-05
      • 2021-02-04
      • 1970-01-01
      • 2020-06-24
      • 2019-10-29
      • 1970-01-01
      相关资源
      最近更新 更多