使用 useEffect 操作状态,但无法正确渲染更新后的状态
Manipulating state with useEffect, but not correctly rendering updated from updated state
我正在使用一些(对我来说)新技术构建一个新的投资组合站点,并且 运行 遇到了一个问题,我可以使用 useState
React hook 设置初始状态,但是当我更新状态时,它不是从新状态渲染的。我试图使用 useEffect
但后来删除了它,但我开始认为我错过了这个 hooks 的一些核心实现概念,并且希望能提供任何建议或推荐阅读来帮助我克服这个障碍。我的代码如下(我提前为糟糕的打字稿道歉,因为这是我试图学习的东西之一,也感谢那里的任何建议):
index.tsx 已更新
import Head from 'next/head'
import { useState } from 'react';
import Body from '../components/Body'
import HeaderItem from "../components/HeaderItem"
import {
UserCircleIcon,
CollectionIcon,
BeakerIcon,
} from '@heroicons/react/outline'
type BodyProps = {
image: string,
text: string,
}
const Intro= {
image: 'https://avatars.githubusercontent.com/u/2357717?v=4',
text: 'Hello this is gonna be the new INTRO body! Hopefully using the body as a component will make single page transitions cleaner'
}
const Skills = {
image: 'https://avatars.githubusercontent.com/u/2357717?v=4',
text: 'Hello this is gonna be the new SKILL body! Hopefully using the body as a component will make single page transitions cleaner'
}
export default function Home({ image, text }: BodyProps) {
const [ currentDisplay, setCurrentDisplay ] = useState(Intro);
const handleClick = (display) => {
setCurrentDisplay({
image: display.image,
text: display.text
});
}
return (
<div className="">
<Head>
<title>Eric Anderson</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<header className='flex flex-col sm:flex-row m-5 justify-between items-center'>
<h1 className="text-2xl pb-10">ERIC ANDERSON</h1>
<div className='flex flex-row justify-evenly max-w-2xl'>
<HeaderItem handleClick={() => handleClick(Intro)} Icon={UserCircleIcon} title='Intro' />
<HeaderItem handleClick={() => handleClick(Skills)} Icon={BeakerIcon} title='Skills' />
<HeaderItem Icon={CollectionIcon} title='Github' />
</div>
</header>
{/* Header - Name github Intro Skills */}
<Body display={currentDisplay}/>
{/* Body req: image=svg && text=string */}
</div>
)
}
components/Body.tsx 已更新
type BodyProps = {
image: string,
text: string,
}
function Body({ display }: BodyProps) {
return (
<div className="flex flex-col items-center justify-center">
<img
className="rounded-full mb-10"
src={display.image} alt="" />
<p className="text-white mx-10">{display.text}</p>
</div>
)
}
export
default Body
components/HeaderItem.tsx
type HeaderProps = {
title: string,
Icon: any,
handleClick?: any,
}
function HeaderItem({title, Icon, handleClick}: HeaderProps ) {
return (
<button
onClick={handleClick}
className="flex flex-col items-center cursor-pointer group w-12 sm:w-20 hover:text-white">
<Icon className='h-8 mb-1 group-hover:animate-bounce '/>
<h1 className='opacity-0 group-hover:opacity-100 tracking-widest'>{title}</h1>
</button>
)
}
export default HeaderItem
最终目标是在单击相应按钮时将 <Body >
组件的图像和文本更新为新值,即。 e.单击“技能”按钮时,我希望从“技能”变量更新状态,并在 Body 组件中显示相关的文本和图像。提前致谢
问题在于我将 props 从 state 对象传递到 Body 组件的方式,并且通过更规范的命名方式暴露出来,特别是将 handleClick
重命名为 onClick
并传递它作为 <button onClick={onClick}....
进入 HeaderItem 并在 index.tsx
中,像这样传递它
<HeaderItem onClick={() =>onClick(Intro)}...
<HeaderItem onClick={() => onClick(Skills)}...
这使我能够在单击时正确调用该函数,它更新了我的状态对象并将显示向下传递给子 Body 组件,在那里它被分解为图像和文本。感谢大家的帮助,既解决了我遇到的问题,又一路教导我
我正在使用一些(对我来说)新技术构建一个新的投资组合站点,并且 运行 遇到了一个问题,我可以使用 useState
React hook 设置初始状态,但是当我更新状态时,它不是从新状态渲染的。我试图使用 useEffect
但后来删除了它,但我开始认为我错过了这个 hooks 的一些核心实现概念,并且希望能提供任何建议或推荐阅读来帮助我克服这个障碍。我的代码如下(我提前为糟糕的打字稿道歉,因为这是我试图学习的东西之一,也感谢那里的任何建议):
index.tsx 已更新
import Head from 'next/head'
import { useState } from 'react';
import Body from '../components/Body'
import HeaderItem from "../components/HeaderItem"
import {
UserCircleIcon,
CollectionIcon,
BeakerIcon,
} from '@heroicons/react/outline'
type BodyProps = {
image: string,
text: string,
}
const Intro= {
image: 'https://avatars.githubusercontent.com/u/2357717?v=4',
text: 'Hello this is gonna be the new INTRO body! Hopefully using the body as a component will make single page transitions cleaner'
}
const Skills = {
image: 'https://avatars.githubusercontent.com/u/2357717?v=4',
text: 'Hello this is gonna be the new SKILL body! Hopefully using the body as a component will make single page transitions cleaner'
}
export default function Home({ image, text }: BodyProps) {
const [ currentDisplay, setCurrentDisplay ] = useState(Intro);
const handleClick = (display) => {
setCurrentDisplay({
image: display.image,
text: display.text
});
}
return (
<div className="">
<Head>
<title>Eric Anderson</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<header className='flex flex-col sm:flex-row m-5 justify-between items-center'>
<h1 className="text-2xl pb-10">ERIC ANDERSON</h1>
<div className='flex flex-row justify-evenly max-w-2xl'>
<HeaderItem handleClick={() => handleClick(Intro)} Icon={UserCircleIcon} title='Intro' />
<HeaderItem handleClick={() => handleClick(Skills)} Icon={BeakerIcon} title='Skills' />
<HeaderItem Icon={CollectionIcon} title='Github' />
</div>
</header>
{/* Header - Name github Intro Skills */}
<Body display={currentDisplay}/>
{/* Body req: image=svg && text=string */}
</div>
)
}
components/Body.tsx 已更新
type BodyProps = {
image: string,
text: string,
}
function Body({ display }: BodyProps) {
return (
<div className="flex flex-col items-center justify-center">
<img
className="rounded-full mb-10"
src={display.image} alt="" />
<p className="text-white mx-10">{display.text}</p>
</div>
)
}
export
default Body
components/HeaderItem.tsx
type HeaderProps = {
title: string,
Icon: any,
handleClick?: any,
}
function HeaderItem({title, Icon, handleClick}: HeaderProps ) {
return (
<button
onClick={handleClick}
className="flex flex-col items-center cursor-pointer group w-12 sm:w-20 hover:text-white">
<Icon className='h-8 mb-1 group-hover:animate-bounce '/>
<h1 className='opacity-0 group-hover:opacity-100 tracking-widest'>{title}</h1>
</button>
)
}
export default HeaderItem
最终目标是在单击相应按钮时将 <Body >
组件的图像和文本更新为新值,即。 e.单击“技能”按钮时,我希望从“技能”变量更新状态,并在 Body 组件中显示相关的文本和图像。提前致谢
问题在于我将 props 从 state 对象传递到 Body 组件的方式,并且通过更规范的命名方式暴露出来,特别是将 handleClick
重命名为 onClick
并传递它作为 <button onClick={onClick}....
进入 HeaderItem 并在 index.tsx
中,像这样传递它
<HeaderItem onClick={() =>onClick(Intro)}...
<HeaderItem onClick={() => onClick(Skills)}...
这使我能够在单击时正确调用该函数,它更新了我的状态对象并将显示向下传递给子 Body 组件,在那里它被分解为图像和文本。感谢大家的帮助,既解决了我遇到的问题,又一路教导我