BBZJUN's
[하나은행] Digital hana 路
JAVA
J1
JavaScript
NEXT
N1
N2
N3_강재준의 과제2셋팅
React
R1
R2
R3
R4 copy
R4
SQL
Spring
TypeScript
T1
T2
T3
T4
공부
JavaScript
기술면접
프론트엔드
코딩테스트
백준
코드트리
알고리즘이름(1)
알고리즘이름(2)
JAVA개념
Home
Contact
Copyright © 2024 |
Yankos
BBZJUN
>
[하나은행] Digital hana 路
> React
...
React
React
리액트 ## 프론트 면접 use디바운스,debounce가 너무 중요하다!! 훅들에 대해서 프론트엔드 기술 면접을 물어본다!! 어떻게 동작이 되는지 알아두기 아침정리 useState useState는 컴포넌트의 상태(state)를 관리하는 훅입니다. 상태는 컴포넌트의 값이나 UI를 동적으로 변경할 때 사용됩니다. import React, { useState } from 'react'; function Counter() { // count는 상태 값, setCount는 상태를 업데이트하는 함수 const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } useState(0)은 count의 초기값을 0으로 설정하고, setCount 함수로 count 값을 변경할 수 있습니다. 버튼을 클릭하면 상태가 증가하고, 컴포넌트가 다시 렌더링됩니다. useRef useRef는 DOM 요소에 접근하거나 렌더링 간 유지해야 하는 값을 저장하는 데 사용됩니다. 렌더링과 상관없이 유지되는 값을 저장하며, 렌더링을 트리거하지 않습니다. import React, { useRef } from 'react'; function TextInputWithFocusButton() { const inputEl = useRef(null); const onFocusClick = () => { // input 요소에 직접 접근해 포커스를 줌 inputEl.current.focus(); }; return ( <div> <input ref={inputEl} type="text" /> <button onClick={onFocusClick}>Focus the input</button> </div> ); } useRef를 통해 inputEl.current로 DOM 요소에 접근할 수 있습니다. onFocusClick을 통해 버튼을 클릭하면 입력 필드에 포커스를 줍니다. useContext useContext는 React의 Context API에서 전역 상태나 데이터를 소비할 때 사용합니다. Context를 통해 컴포넌트 트리에서 값을 props로 전달하지 않고 사용할 수 있습니다. import React, { createContext, useContext, useState } from 'react'; const UserContext = createContext(null); function App() { const [user, setUser] = useState({ name: 'John', age: 30 }); return ( <UserContext.Provider value={user}> <Profile /> </UserContext.Provider> ); } function Profile() { const user = useContext(UserContext); return <div>{`Hello, ${user.name}!`}</div>; } UserContext.Provider에서 user 데이터를 하위 컴포넌트에 전달하고, Profile 컴포넌트에서 useContext(UserContext)를 사용해 user 값을 가져옵니다. useEffect useEffect는 컴포넌트가 렌더링되거나 업데이트될 때 부수 효과를 처리하기 위해 사용됩니다. 예를 들어, 데이터 패칭, 이벤트 리스너 등록/제거, 타이머 설정 등을 처리할 때 유용합니다. import React, { useState, useEffect } from 'react'; function Timer() { const [count, setCount] = useState(0); useEffect(() => { const timer = setInterval(() => { setCount((prevCount) => prevCount + 1); }, 1000); // 컴포넌트가 언마운트될 때 타이머를 정리함 return () => clearInterval(timer); }, []); return <div>{count}</div>; } useEffect는 컴포넌트가 렌더링될 때 타이머를 시작하고, 컴포넌트가 언마운트되면 타이머를 정리합니다. 타이머는 1초마다 count 값을 증가시킵니다. useLayoutEffect useLayoutEffect는 DOM이 업데이트된 후 바로 실행되며, 화면에 그려지기 전에 동기적으로 실행됩니다. DOM 조작이 필요할 때 사용됩니다. import React, { useState, useLayoutEffect, useRef } from 'react'; function LayoutEffectExample() { const [size, setSize] = useState(0); const divRef = useRef(null); useLayoutEffect(() => { // div의 너비를 가져와서 상태로 저장 if (divRef.current) { setSize(divRef.current.offsetWidth); } }); return ( <div> <div ref={divRef} style={{ width: '100px', height: '100px', backgroundColor: 'lightblue' }} /> <p>Div width: {size}px</p> </div> ); } useLayoutEffect는 DOM이 업데이트된 후 동기적으로 실행되며, div의 크기를 계산해 size 상태로 저장합니다. useCallback useCallback은 특정 함수의 재생성을 방지하는 훅입니다. 컴포넌트가 렌더링될 때마다 불필요하게 함수가 다시 생성되는 것을 막고, 성능 최적화에 도움을 줍니다. import React, { useState, useCallback } from 'react'; function Counter() { const [count, setCount] = useState(0); const increment = useCallback(() => { setCount((prevCount) => prevCount + 1); }, []); return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); } useCallback을 사용해 increment 함수가 재생성되지 않도록 설정했습니다. 이는 컴포넌트가 불필요하게 렌더링되지 않도록 방지합니다. useMemo useMemo는 특정 값의 재계산을 방지하고, 메모이제이션을 통해 성능 최적화를 수행합니다. 컴포넌트가 렌더링될 때마다 값이 다시 계산되지 않도록 제어할 수 있습니다. import React, { useState, useMemo } from 'react'; function ExpensiveCalculation(num) { console.log('Expensive calculation...'); return num * 2; } function Calculator() { const [number, setNumber] = useState(0); const [text, setText] = useState(''); const doubledNumber = useMemo(() => ExpensiveCalculation(number), [number]); return ( <div> <input value={text} onChange={(e) => setText(e.target.value)} placeholder="Type something" /> <button onClick={() => setNumber(number + 1)}>Increment Number</button> <p>Doubled Number: {doubledNumber}</p> </div> ); } useMemo를 사용해 ExpensiveCalculation 함수가 number 값이 변경될 때만 다시 실행되도록 합니다. 이를 통해 불필요한 재계산을 방지합니다. 테일윈드 $ yarn add tailwind-merge https://www.npmjs.com/package/tailwind-merge clsx yarn add clsx 라우팅 yarn add react-router-dom yarn add -D @types/react-router-dom
[하나은행] Digital hana 路
· 2024-09-30
React
리액트 깃허브로 페이지 배포(간단히) master 브런치로 이동하여서(당연히 dev꺼를 add, 커밋해두고!) merge를 해서 dev브런치꺼를 합쳐둔다!! 그리고 설치 공통 (배포 전) $> yarn add gh-pages -D # npm i gh-pages -D package.json > script > "deploy": "gh-pages -d dist", 추가! 추가설정 Deploying to https://<USERNAME>.github.io/<REPO> # 1. vite.config.ts에서 base 설정 export default defineConfig({ plugins: [react()], base: '/<REPO>/', // ex. base: '/hana4/', }); # 1. main.tsx > BrowserRouter →→ HashRouter // github은 try_files를 줄 수 없으므로 #으로 링크! # 2. add & commit into master(main) branch # 3. run build & deploy $> yarn build # npm run build vite build $> yarn deploy # https://indiflex.github.io/hana4 // 브라우저 cache면 쿠키 제거! https://<github-id>.github.io/<repository> Cf. git push -f git@github.com:indiflex/hana4.git main:gh-pages 깃허브 해당 리파지토리 폴더에 들어가서 세팅-> Pages -> 브런치 선택(gh-pages) ->완료 stroybook/스토리북 storybook.js.org $> npx storybook@latest init $> yarn storybook
[하나은행] Digital hana 路
· 2024-09-30
React
리액트 Hook, 훅 상태관리 Hooks useState useContext (createContext) useReducer 시점 Hooks useLayoutEffect (render후, sync) useEffect (paint후, async) 메모화 Hooks useMemo useCallback memo 그 외 Hooks useRef, useImperativeHandle useDebugValue, useId state const [상태변수, 세터] = useState(초깃값/초기화함수);로 초기화를 해서 바꾸어주어야한다
[하나은행] Digital hana 路
· 2024-09-23
React
리액트 설치 <git bash> 필수 설치 - node/npm: https://nodejs.org (by NVM / Volta) $> nvm install --lts $> nvm use v20.10.0 $> nvm alias default v20.10.0 - npx: $> npx -v # 없다면.. - $> npm i npx -g - vscode: https://code.visualstudio.com/download 기타 - React DevTools # 리액트 개발자 도구 - yarn: npm i yarn -g # brew install yarn - vite: https://vitejs-kr.github.io/ - git: https://git-scm.com/download 설정 <git bash> vite >= node v14.18 or LTS $> yarn create vite <rbvite> # yarn create vite rbvite --template react-ts # npm init vite@latest rbvite # in rb $> cd rbvite $> yarn # npm i $> yarn build # npm run build $> yarn dev //으로 실행 확장팩 <vscode> prettier ESLint 초기 설정 <git bash> $> yarn add -D eslint-plugin-react $> yarn add -D eslint-plugin-jsx-a11y # 접근성 <.eslintrc.cjs> .eslintrc.cjs bold 부분 수정! module.exports = { env: { browser: true, es2021: true, node: true }, extends: [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:react/jsx-runtime', 'plugin:jsx-a11y/recommended', ], overrides: [], parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: 'latest', sourceType: 'module', }, plugins: ['react-refresh', 'react-hooks', 'jsx-a11y'], rules: { 'react/react-in-jsx-scope': 'off', 'react/jsx-uses-react': 'off', 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn', 'react/prop-types': 'off', 'react/no-array-index-key': 'error', }, settings: { react: { version: 'detect' }, // for react version warnning }, }; <git bash> install $> yarn add -D prettier eslint-config-prettier eslint-plugin-prettier $> yarn prettier # package.json > script > "prettier": "prettier --write .", .eslintrc.cjs bold 부분 추가! export default { env: { browser: true, es2021: true, }, extends: [ …, 'plugin:prettier/recommended', ], overrides: [], parserOptions: { … }, plugins: ['react', 'react-hooks', 'jsx-a11y', 'prettier']], rules: { …, 'prettier/prettier': 'error', quotes: ['error', 'single', { allowTemplateLiterals: true }], }, … }; /// .prettierrc 파일 생성! { "singleQuote": true, "jsxSingleQuote": true, "semi": true, "trailingComma": "es5" } // prettier 기타 "endOfLine": "auto", "tabWidth": 2, "useTabs": false, "printWidth": 100 <eslint.config.js> import js from '@eslint/… import react from 'eslint-plugin-react'; import prettier from 'eslint-plugin-prettier'; import eslintConfigPrettier from 'eslint-config-prettier'; export default tseslint.config( … plugins: { 'react-hooks': reactHooks, 'react-refresh': reactRefresh, react, prettier, }, settings: { react: { version: '18.3' }, // React version for react plugin }, rules: { ...js.configs.recommended.rules, // ESLint rules ...react.configs.recommended.rules, // React rules ...react.configs['jsx-runtime'].rules, // JSX rules ...reactHooks.configs.recommended.rules, 'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true }, ], 'prettier/prettier': 'error', }, }, eslintConfigPrettier ); <eslint.config.js> import jsxA11y from 'eslint-plugin-jsx-a11y'; export default tseslint.config( { ignores: ['dist'] }, { extends: [js.configs.recommended, ...tseslint.configs.recommended], … plugins: { 'react-hooks': reactHooks, 'react-refresh': reactRefresh, react, prettier, 'jsx-a11y': jsxA11y, }, settings: { react: { version: '18.3' }, }, rules: { ... ...reactHooks.configs.recommended.rules, 'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true }, ], 'prettier/prettier': 'error', 'jsx-a11y/alt-text': 'error', }, }, eslintConfigPrettier );
[하나은행] Digital hana 路
· 2024-09-20
React
리액트 카카오 프론트코테 구현문제 ReactDOM.render( // 기존 렌더링 방식(sync) React.createElement('h1', null, 'A'), document.getElementById('root') ); const root = ReactDOM.createRoot( // concur document.getElementById('root') ); const element = <h1>Hello, world</h1>; root.render(element); 이 코드는 React 17까지 사용되던 동기식(Synchronous) 렌더링 방식을 사용합니다. ReactDOM.render() 메소드는 DOM에 직접 렌더링을 수행하며, React 요소를 document.getElementById(‘root’) 위치에 렌더링합니다. 이 방식에서는 UI 업데이트가 동기적으로 처리되므로, 매우 큰 작업이 있을 때는 브라우저가 잠시 멈출 수 있습니다. 컴포넌트 //~components/Hello.tsx const Title = ({text, name}:{text:string, name:string}) => <h3>{text}aaaaaaaaaaaaaaaaaa{name}aaaaaaaaaaaaaaaaaaa</h3> //위의 화살표 함수 export default function Hello(){ return <> <Title text = "kkkkkkkkkkkkkk" name="jjjaejjjaejae" /> <h1>hhheoolllo</h1> <div>gggg zzz oooooooooooooo</div> <div className="red" style={{color:'blue'}}>gggg zzz oooooooooooooo</div> //style 선언은 {}로 열고 객체로 넣어주기 </> //export default function으로 만들어서 넣기 }
[하나은행] Digital hana 路
· 2024-09-19
<
>
Touch background to close