我正在使用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>
);
}
答案 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:)