Skip to content

Commit

Permalink
useImperativeHandle
Browse files Browse the repository at this point in the history
  • Loading branch information
Dongha Kim authored and Dongha Kim committed Mar 10, 2023
1 parent 2251772 commit 7e5ed42
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 1 deletion.
124 changes: 124 additions & 0 deletions src/AdvancedHook/aboutImperative.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React, { useImperativeHandle } from "react";
import { useLayoutEffect, useRef, useState } from "react";
import "./index.css";

const MessagesDisplay = React.forwardRef(
({ messages }: { messages: any }, ref: any) => {
const containerRef = useRef<HTMLDivElement>(null);

useLayoutEffect(() => {
if (containerRef.current) {
scrollToBottom();
}
});

useImperativeHandle(
ref,
() =>
(ref.current = {
scrollToTop,
scrollToBottom,
})
);

function scrollToTop() {
if (containerRef.current) {
containerRef.current.scrollTop = 0;
}
}

function scrollToBottom() {
if (containerRef.current) {
containerRef.current.scrollTop = containerRef.current.scrollHeight;
}
}

return (
<div ref={containerRef} role="log">
{messages.map((message: any, index: number, array: any[]) => (
<div key={message.id}>
<strong>{message.author}</strong>: <span>{message.content}</span>
{array.length - 1 === index ? null : <hr />}
</div>
))}
</div>
);
}
);

function AboutImperative() {
const [messages, setMessages] = useState(allMessages.slice(0, 8));
const messageDisplayRef = useRef<any>(null);

const addMessage = () =>
messages.length < allMessages.length
? setMessages(allMessages.slice(0, messages.length + 1))
: null;
const removeMessage = () =>
messages.length > 0
? setMessages(allMessages.slice(0, messages.length - 1))
: null;

const scrollToTop = () =>
messageDisplayRef.current && messageDisplayRef.current.scrollToTop();
const scrollToBottom = () =>
messageDisplayRef.current && messageDisplayRef.current.scrollToBottom();

return (
<div className="messaging-app">
<div style={{ display: "flex", justifyContent: "space-between" }}>
<button onClick={addMessage}>메시지 추가하기</button>
<button onClick={removeMessage}>메시지 삭제하기</button>
</div>
<hr />
<hr />
<div>
<button onClick={scrollToTop}>scroll to top</button>
</div>
<MessagesDisplay ref={messageDisplayRef} messages={messages} />
<div>
<button onClick={scrollToBottom}>scroll to bottom</button>
</div>
</div>
);
}

export default AboutImperative;

const allMessages = [
`Leia: Aren't you a little short to be a stormtrooper?`,
`Luke: What? Oh... the uniform. I'm Luke Skywalker. I'm here to rescue you.`,
`Leia: You're who?`,
`Luke: I'm here to rescue you. I've got your R2 unit. I'm here with Ben Kenobi.`,
`Leia: Ben Kenobi is here! Where is he?`,
`Luke: Come on!`,
`Luke: Will you forget it? I already tried it. It's magnetically sealed!`,
`Leia: Put that thing away! You're going to get us all killed.`,
`Han: Absolutely, Your Worship. Look, I had everything under control until you led us down here. You know, it's not going to take them long to figure out what happened to us.`,
`Leia: It could be worse...`,
`Han: It's worse.`,
`Luke: There's something alive in here!`,
`Han: That's your imagination.`,
`Luke: Something just moves past my leg! Look! Did you see that?`,
`Han: What?`,
`Luke: Help!`,
`Han: Luke! Luke! Luke!`,
`Leia: Luke!`,
`Leia: Luke, Luke, grab a hold of this.`,
`Luke: Blast it, will you! My gun's jammed.`,
`Han: Where?`,
`Luke: Anywhere! Oh!!`,
`Han: Luke! Luke!`,
`Leia: Grab him!`,
`Leia: What happened?`,
`Luke: I don't know, it just let go of me and disappeared...`,
`Han: I've got a very bad feeling about this.`,
`Luke: The walls are moving!`,
`Leia: Don't just stand there. Try to brace it with something.`,
`Luke: Wait a minute!`,
`Luke: Threepio! Come in Threepio! Threepio! Where could he be?`,
].map((m, i) => ({
id: i,
author: m.split(": ")[0],
content: m.split(": ")[1],
}));
4 changes: 3 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Counter from "./AdvancedHook";
import ContextComponent from "./AdvancedHook/aboutContext";
import Cache from "./Cache";
import AboutLayoutEffect from "./AdvancedHook/aboutLayoutEffect";
import AboutImperative from "./AdvancedHook/aboutImperative";

function App() {
return (
Expand All @@ -26,7 +27,8 @@ function App() {
{/* <Counter /> */}
{/* <ContextComponent /> */}
{/* <Cache /> */}
<AboutLayoutEffect />
{/* <AboutLayoutEffect /> */}
<AboutImperative />
</div>
);
}
Expand Down

0 comments on commit 7e5ed42

Please sign in to comment.