1const timer = new Promise((resolve) => {2 setTimeout(() => {3 resolve(true);4 }, 100);5});6
7timer.then(() => {8 console.log('Time out!');9});
1let timerResolve = null;2
3const timer = new Promise((resolve) => {4 timerResolve = resolve;5});6
7setTimeout(() => {8 timerResolve();9}, 100);10
11timer.then(() => {12 console.log('Time out!');13});
new Promise((resolve, reject) => { ... })
를 쉽게 대체할 수 있도록 만들어진 함수로 Promise 객체와 resolve/reject 함수를 한꺼번에 깔끔하게 얻을 수 있게 해준다.
1const { promise: timer, resolve: timerResolve } = Promise.withResolvers(); // { promise, resolve, reject }2
3setTimeout(() => {4 timerResolve();5}, 100);6
7timer.then(() => {8 console.log('Time out!');9});
1import { useRef, useEffect } from 'react';2
3interface Props {4 state: 'A' | null;5}6
7const Component = ({ state }: Props) => {8 const ref = useRef<HTMLDivElement | null>(null);9
10 useEffect(() => {11 if (ref.current === null) {12 return;13 }14
15 ref.current.scrollTo({ top: 0 }); // 최초 상태값이 null이라면 상태값이 A로 변경되어도 해당 로직이 실행되지 않음.16 }, []);17
18 if (state === null) {19 return null;20 }21
22 return <div ref={ref}>A</div>;23};
1interface Props {2 state: 'A' | null;3}4
5const Component = ({ state }: Props) => {6 const [{ promise: waitForElement, resolve: elementRendered }] = useState(() => {7 return Promise.withResolvers();8 });9
10 useEffect(() => {11 waitForElement.then(() => {12 ref.current.scrollTo({ top: 0 }); // target element 렌더링 후 실행됨을 보장13 });14 }, [waitForElement]);15
16 if (state === null) {17 return null;18 }19
20 return <div ref={elementRendered}>A</div>;21};