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

时间:2019-09-24 20:52:36

标签: javascript reactjs react-hooks

我正在使用freeCodeCamp鼓机应用程序。在带有功能箭头组件的应用程序中,我在父组件中使用useState钩子设置了display的状态,并将其作为道具传递给子组件。在父组件中,我尝试在div中呈现display状态。但是,触发该方法时(单击“ drum pad” div),该应用程序将崩溃。在控制台中,我收到一条错误消息:“未捕获的不变违反:对象作为React子对象无效(找到:带有键{display}的对象)。如果要渲染子代集合,请改用数组。” 我一直在关注该项目的YouTube教程,但是使用箭头功能组件和Hooks代替了教程中使用的常规类-在教程中(this video的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 个答案:

答案 0 :(得分:4)

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

const handleDisplay = display => {
  setDisplay(display);
}

答案 1 :(得分:1)

已经回答了这个问题,但是由于您正在学习教程,所以我假设您正在学习React,并希望指出几点以帮助您:)

指出了状态的不正确使用,但只是为了澄清(以及我认为您使用对象的原因):以“旧”方式,对于Class组件,状态曾经是对象,而您需要像一个对象一样更新它。此example here显示了这一点。使用Hooks,您不需要设置整个State对象,只需设置特定的state属性。更多信息here

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

最后一点是,在使用循环创建组件(例如将<DrumPad>map一起使用时),您需要provide a "key" attribute。这将有助于React跟踪需要更新或重新呈现的内容。

如果您希望代码有效,请使用此链接中的更改更新代码:

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

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