开发者问题收集

React Hooks——未捕获的不变违规:对象作为 React 子对象无效

2019-09-24
5026

我正在开发 freeCodeCamp 鼓机应用程序。在我的应用程序中,使用函数箭头组件,我使用父组件中的 useState 钩子设置 display 的状态,并将其作为 prop 传递给子组件。在父组件中,我尝试在 div 中呈现 display 状态。但是,当触发该方法时(单击“鼓垫”div),应用程序崩溃。在控制台中,我收到一条错误消息,提示“未捕获的不变违规:对象作为 React 子项无效(找到:带有键 {display} 的对象)。如果您想要呈现子项集合,请改用数组。” 我一直在关注这个项目的 YouTube 教程,但使用箭头函数组件和 Hooks 而不是教程中使用的常规类 - 在教程中( 本视频 的 1:55 左右)有人成功完成了我想做的事情,所以我认为问题与使用 Hooks 或箭头函数组件有关。

// APP COMPONENT (PARENT)

const sounds = [
  { id: 'snare', letter: 'Q', src: 'https://www.myinstants.com/media/sounds/snare.mp3' },
  // etc.
];

const App = () => {

  const [display, setDisplay] = useState(''); // <----

  const handleDisplay = display => { // <----
    setDisplay({ display });
  }

  return (
    <div className="App">
      <div className="drum-machine">
        <div className="display">
          <p>{display}</p> // <---- Related to error in console
        </div>
        <div className="drum-pads">
          {sounds.map(sound => (
            <DrumPad
              id={sound.id}
              letter={sound.letter}
              src={sound.src}
              handleDisplay={handleDisplay} // <----
            />
          ))}
        </div>
      </div>
    </div>
  );
}

// DRUMPAD COMPONENT (CHILD)

const DrumPad = ({ id, letter, src, handleDisplay }) => {

  let audio = React.createRef();

  const handleClick = () => {
    audio.current.play();
    audio.current.currentTime = 0;
    handleDisplay(id); // <----
  }

  return (
    <div
      className="drum-pad"
      id={id}
      onClick={handleClick}
    >
      <p className="letter">{letter}</p>
      <audio
        ref={audio}
        id={letter}
        src={src}
      >
      </audio>
    </div>
  );
}
2个回答

您正在将状态设置为对象而不是字符串。删除它周围的花括号。

const handleDisplay = display => {
  setDisplay(display);
}
Kamran Nazir
2019-09-24

这个问题已经得到解答,但由于您正在学习教程,我假设您正在学习 React,并想指出一些可以帮助您的事情 :)

有人指出了状态的错误使用,但只是为了澄清(以及我认为您使用对象的原因):在“旧”方式中,使用 Class 组件,状态曾经是一个对象,您需要像对象一样更新它。此 此处的示例 显示了这一点。使用 Hooks,您不需要设置整个 State 对象,只需设置特定的状态属性。更多信息请见 此处

另一点是,至少在您的 CodePen 示例中,您缺少 useState 的导入。您需要像这样 import { useState } from React 导入它,或者像这样 React.useState 使用它,因为这是一个单独的模块,在导入 React 时不会默认导入。

最后一点是,当使用循环创建组件时(例如带有 map<DrumPad> ),您需要 提供“key”属性 。这将有助于 React 跟踪需要更新或重新渲染的内容。

如果您想看到它正常工作,请在此链接中使用这些更改更新您的代码:

https://codesandbox.io/s/reverent-browser-zkum2

祝您好运,希望您喜欢 React Hooks :)

Bruno Monteiro
2019-09-24