我有一个组件可以用作我的单页网站的首页。
我有以下内容:
<div className="flex mb-0 items-center">
<h2 className="capitalize tracking-tight text-4xl mt-16 mr-8 md:mt-24 font-black hvr-underline-from-left pb-1">
recent projects
</h2>
<h2 className="capitalize tracking-tight text-4xl mt-16 md:mt-24 font-black text-gray-400 hvr-underline-from-left pb-1">
open source
</h2>
</div>
<Projects />
<OpenSource />
当前,我的组件显示在彼此下面。我希望能够在两者之间切换,如果用户单击“最近的项目”,它将显示<Projects />
组件。如果用户单击“开源”,它将隐藏<Projects />
组件并显示<OpenSource/>
。
我很想创建像幻灯片这样的动画,并带有类似react spring的东西。但是很高兴现在让他们切换。
有什么建议吗?
import React, { useState, useCallback } from "react";
export default function App() {
const [activeComponent, setActiveComponent] = useState("projects");
const modifyActiveComponent = useCallback(
newActiveComponent => {
setActiveComponent(newActiveComponent);
},
[setActiveComponent]
);
return (
<>
<div className="flex mb-0 items-center">
<h2
onClick={() => modifyActiveComponent("projects")}
className="capitalize tracking-tight text-4xl mt-16 mr-8 md:mt-24 font-black hvr-underline-from-left pb-1"
>
recent projects
</h2>
<h2
onClick={() => modifyActiveComponent("open_source")}
className="capitalize tracking-tight text-4xl mt-16 md:mt-24 font-black text-gray-400 hvr-underline-from-left pb-1"
>
open source
</h2>
</div>
{activeComponent === "projects" && <h1>Projects</h1>}
{activeComponent === "open_source" && <h1>OpenSource</h1>}
</>
);
}
上面,我创建了一个简单的示例来切换两个组件。我使用了useState
钩子来保存活动组件。我还为代码添加了useCallback
钩子以处理对项目的单击并随后更新了活动组件。
您可以播放演示:https://codesandbox.io/s/lucid-carson-jghdi?file=/src/App.js:0-1042
我用react转换组https://codesandbox.io/s/epic-curie-nq3wo?file=/src/App.js
在那里您可以看到动画效果,可以定义每个过渡和很多有趣的东西。
(我在.section-exit
中做了一个小技巧,以便能够显示出平滑的过渡效果,即position: absolute
,没有重叠的部分。
文档: https://github.com/reactjs/react-transition-group
JS: https://codesandbox.io/s/epic-curie-nq3wo?file=/src/App.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { CSSTransition } from "react-transition-group";
import "./styles.css";
function App() {
const sections = ["PROJECTS", "OPENSOURCE"];
const [activeSection, setActiveSection] = useState(sections[0]);
const setProject = () => setActiveSection(sections[0]);
const setOpenSource = () => setActiveSection(sections[1]);
return (
<div>
<button onClick={setProject}>Project</button>
<button onClick={setOpenSource}>Open Source</button>
<CSSTransition
classNames="section"
in={activeSection === sections[0]}
timeout={300}
unmountOnExit
>
<h1>Projects</h1>
</CSSTransition>
<CSSTransition
classNames="section"
in={activeSection === sections[1]}
timeout={300}
unmountOnExit
>
<h1>Open Source</h1>
</CSSTransition>
</div>
);
}
export default App;
CSS: https://codesandbox.io/s/epic-curie-nq3wo?file=/src/styles.css
.section-enter {
opacity: 0;
transform: translateX(100%);
}
.section-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity 300ms, transform 300ms;
}
.section-exit {
opacity: 1;
position: absolute;
}
.section-exit-active {
opacity: 0;
transform: translateX(100%);
transition: opacity 300, transform 300;
}
在那里您可以看到效果。