TS스터디 팀원들과 함께 매주 주차별 과제를 진행합니다
https://github.com/bradtraversy/vanillawebprojects
const main = document.getElementById('main') as HTMLDivElement;
const addUserBtn = document.getElementById('add-user') as HTMLButtonElement;
const doubleBtn = document.getElementById('double') as HTMLButtonElement;
const showMillionairesBtn = document.getElementById(
'show-millionaires',
) as HTMLButtonElement;
const sortBtn = document.getElementById('sort') as HTMLButtonElement;
const calculateWealthBtn = document.getElementById(
'calculate-wealth',
) as HTMLButtonElement;
let currentStateKey = 0; // useState가 실행 된 횟수
type setStateFunc<T> = (state: Promise<T>) => void;
const states: any = []; // state를 보관할 배열
type userType = {
name: string;
money: number;
};
type statesType = userType[];
const useState = <T>(initState: T | Promise<T>): [T, setStateFunc<T>] => {
// initState로 초기값 설정
const key: number = currentStateKey;
if (states.length === key) {
states.push(initState);
}
// state 할당
const state = states[key] as T;
const setState = (newState: Promise<T>) => {
// 값이 똑같은 경우
if (newState === state) return;
if (JSON.stringify(newState) === JSON.stringify(state)) return;
// 기존 값과 다른 경우에만 값을 변경하고 render()를 실행한다.
states[key] = newState;
console.log('render 호출');
render();
};
currentStateKey += 1;
return [state, setState];
};
async function getRandomUser(num: number) {
const arr = [];
for (let i = 0; i < num; i++) {
const result = (await (await fetch('https://randomuser.me/api')).json())
.results[0];
const newUser = {
name: `${result.name.first} ${result.name.last}`,
money: Math.floor(Math.random() * 1000000),
};
arr.push(newUser);
}
return arr;
}
const Component = async () => {
const [userInfo, setUserInfo] = useState(getRandomUser(3));
console.log(userInfo);
return userInfo;
};
const render = async () => {
const data = await Component();
main.innerHTML = '<h2><strong>Person</strong> Wealth</h2>';
console.log(data);
data.forEach((item) => {
const element = document.createElement('div');
element.classList.add('person');
element.innerHTML = `<strong>${item.name}</strong> ${item.money}`;
main.appendChild(element);
});
currentStateKey = 0;
};
render();
type userInfoObj = {
name: string;
money: number;
};
type statesType = userInfoObj[];
const states: statesType = [];
리액트의 useState()를 구현해보는 과정에서 사용한 로직입니다
상태를 변수가 아닌 함수로 사용하고 있으며, 그 외에도 리액트와
완벽히 똑같이 작동하지는 않지만 아래의 기능들을 구현했습니다
자세한 설명은 바닐라로 useState 구현해보기
const useState = <T extends statesType>(status: T): [() => T, (state: T) => void] => {
let initialState = status;
const state = () => initialState as T;
const setState = (newState: T) => {
initialState = newState;
render();
};
return [state, setState];
};
// 상태를 리턴하는 함수 , 상태를 업데이트 하는 함수
const [getUserInfo, setUserInfo] = useState(states);
const render = (): void => {
main.innerHTML = `<h2><strong>Person</strong> Wealth</h2>`;
for (let i of getUserInfo()) {
let state = i;
let htmlString : string = '';
const newElement = document.createElement('div') as HTMLDivElement;
newElement.classList.add('person');
htmlString += `<strong>${state.name}</strong> ${state.money}`;
newElement.innerHTML = htmlString;
main.appendChild(newElement);
}
};
const getUser = async (num: number): Promise<userInfoObj[]> => {
let dataArr = [];
for (let i = 0; i < num; i++) {
const result = (await (await fetch('https://randomuser.me/api')).json())
.results[0];
const newUser = {
name: `${result.name.first} ${result.name.last}`,
money: Math.floor(Math.random() * 1000000),
};
dataArr.push(newUser);
}
return dataArr;
};
const init = async () : Promise<void> => {
const userData = await getUser(3);
setUserInfo(userData);
};
init();