본문 바로가기
언어 정리/React, Nodejs, Express

React - 정리

by 알 수 없는 사용자 2024. 9. 20.

 

 

https://nextleap.app/online-compiler/reactjs-programming

 

React Online Compiler | Code, Compile, and Debug React Apps - NextLeap

Experience the power of React with NextLeap's Online Compiler. Write, compile, and debug React applications online in real-time. Boost your productivity and enhance your React development workflow with our intuitive platform.

nextleap.app

이 사이트로 간편하게 컴파일 가능


from 'react';

useState

특정 타겟을 리렌더링 하기 위한 함수

ex)  import React, { useState } from "react";
useState( 초기화할 값 )

 

1. onClick 이벤트 핸들러로 changeColor 함수 실행
2. setColor 함수로 color 상태 변수 변경
3. color 상태 변수 변경시, React가 해당 컴포넌트 리렌더링

import React, { useState } from 'react';

function ColorChanger() {
  // color라는 상태 변수와 setColor라는 상태 업데이트 함수를 선언합니다.
  const [color, setColor] = useState('white');

  // 버튼을 클릭할 때마다 배경색을 변경합니다.
  const changeColor = () => {
    const newColor = color === 'white' ? 'lightblue' : 'white';
    setColor(newColor);
  };

  return (
    <div style={{ backgroundColor: color, padding: '20px', textAlign: 'center' }}>
      <p>배경색을 변경하려면 버튼을 클릭하세요.</p>
      <button onClick={changeColor}>색상 변경</button>
    </div>
  );
}

export default ColorChanger;

 

 


useReducer

복잡한 상태 로직을 관리하기 위해 리듀서 패턴을 사용하는 React 훅

상태가 더 복잡하거나 상호 연관된 상태 일 때 useReducer 을 쓰면 코드가 더 간단해진다.

ex) import React, { useCallback, useReducer } from "react";

useReducer( dispatch때 호출할 함수, 호출할 함수의 첫번째 인자(accumulateState)의 초기 값 )

1. dispatch 로 reducer 함수를 호출 하고 
2. dispatch 에 들어가는 인자값은 reducer 의 action 에 으로 전달된다.
3. reducer 의 첫번째 인자인 accumulateState 에는 초기값이 들어 있고, 함수가 새로 호출되어도 값은 유지된다.
4. reducer 함수가 return 하는 값들은 useReducer 함수에서 return 됬던 stateResult에 업데이트된다.
5. useReducer 에서 return 됬던 stateResult 값이 이전 값과 다르면 리렌더링 한다.

// useReducer 간단 예시
/** useReducer( dispatch때 호출할 함수, 호출할 함수의 첫번째 인자(accumulateState)의 초기 값 )
 */

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(accumulateState, action) {
  switch (action.type) {
    case 'increment':
      return { count: accumulateState.count + 1 };
    case 'decrement':
      return { count: accumulateState.count - 1 };
    default:
      throw new Error();
  }
}

const Counter = () => {
  const [stateResult, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {stateResult.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
    </div>
  );
};

export default Counter;

 

 


useCallback

함수 컴포넌트에서 함수를 메모이제이션하여 불필요한 재생성을 방지하는 React 훅
메모이제이션 : 함수의 실행 결과를 저장하여 동일한 입력에 대해 반복 계산을 피하고 성능을 향상시키는 최적화 기법
-> 함수내에서 함수를 반복적으로 실행시, 새로운 함수 인스턴스가 반복적으로 생성되는데 이 문제를 해결하기 위한 코드

ex) import React, { useCallback, useReducer } from "react";
const aHandler = useCallback(aHandler에 대입할 함수, 함수인스턴스 생성 의존성)

 

useCallback( () => {A함수}, []) 
<- 의존성없이 A함수의 참조를 고정 (초기 렌더링 시 한 번만 생성)

const arrowFunction = useCallback( () => {A함수}, [의존성배열, ... n개]) 
<- 의존성배열에 [포함된 변수 or 함수참조] 변경될 때마다, A함수호출
<- A함수 호출 : arrowFunction 함수 새로 생성 (참조 변경==인스턴스 생성)

import { useState, useCallback, useEffect } from "react";

const MyComponent = () => {
  const [count, setCount] = useState(0);

  const arrowFunction = useCallback(() => {
    setCount(count + 1);
  }, [count]); // count가 변경될 때마다, arrowFunction 새로 생성됨

  useEffect(() => {
    console.log(count);
  }, [arrowFunction]); // count -> increment 호출 -> 참조 변경 -> 콘솔로그!

return <button onClick={arrowFunction}>Increment</button>;
};

export default MyComponent;

 

 


useEffect

컴포넌트가 렌더링될 때와 상태나 props가 변경될 때 부수 효과(side effects)를 수행하는 React 훅

ex) import React, { useRef, useEffect } from "react";
useEffect( 의존성변수가 바뀔 떄마다 호출할 함수, 의존성 변수 )

 

1. useEffect함수의 의존성변수로 count 를 지정
2. "로딩 중..." 출력
3. 버튼 클릭스 count 하나씩 Up 시킴
4. count 가 의존 변수이므로 useEffect에 등록한 함수 호출
5. 'https://jsonplaceholder.typicode.com/posts/1' 읽어서 화면에 출력 + Up된 count 출력

 

useEffect 의 async await 형식

// useEffect 간단 예시

import React, { useState, useEffect } from 'react';

const DataFetcher = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [count, setCount] = useState(0); // 버튼 클릭 시 변경되는 상태 변수

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true); // 새로운 요청을 시작할 때 로딩 상태로 설정
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
        const data = await response.json();
        setData(data);
      } catch (error) {
        console.error('데이터를 가져오는 중 오류가 발생했습니다:', error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [count]); // count가 변경될 때마다 실행

  if (loading) {
    return <p>로딩 중...</p>;
  }

  return (
    <div>
      <h1>데이터 가져오기 예제</h1>
      {data ? <pre>{JSON.stringify(data, 2)}</pre> : <p>데이터가 없습니다.</p>}
      <button onClick={() => setCount(count + 1)}>데이터 다시 가져오기</button>
      <p> Count : {count}</p>
    </div>
  );
};

export default DataFetcher;

 

useEffect 의 Promise 형식

// useEffect 간단 예시

import React, { useState, useEffect } from 'react';

const DataFetcher = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [count, setCount] = useState(0); // 버튼 클릭 시 변경되는 상태 변수

  useEffect(() => {
    // JSONPlaceholder API에서 데이터를 가져옵니다.
    setLoading(true); // 새로운 요청을 시작할 때 로딩 상태로 설정
    fetch('https://jsonplaceholder.typicode.com/posts/1')
      .then(response => response.json())
      .then(data => {
        setData(data);
        setLoading(false);
      })
      .catch(error => {
        console.error('데이터를 가져오는 중 오류가 발생했습니다:', error);
        setLoading(false);
      });
  }, [count]); // count가 변경될 때마다 실행

  if (loading) {
    return <p>로딩 중...</p>;
  }

  return (
    <div>
      <h1>데이터 가져오기 예제</h1>
      {data ? <pre>{JSON.stringify(data, 2)}</pre> : <p>데이터가 없습니다.</p>}
      <button onClick={() => setCount(count + 1)}>데이터 다시 가져오기</button>
      <p1> Count : {count}</p1>
    </div>
  );
};

export default DataFetcher;

 

useEffect 로 초기 한번만 실행 시키기 vs useState 만 써서 초기 한번만 실행 시키기

/* useState 만 써서 초기 한번만 실행 시키기  */
// import React, { useState } from "react";

// const someFunction = () => {
//   const [isValid, setIsValid] = useState({ b: 1 });
//   const [initialized, setInitialized] = useState(false);

//   if (!initialized) {
//     setIsValid({ a: 1 });
//     setInitialized(true);
//   }

//   const currentValid = isValid;
//   console.log(currentValid);

//   return (
//     <div>
//       <h1>{JSON.stringify(currentValid)}</h1> {/* 객체를 문자열로 변환하여 출력 */}
//     </div>
//   );
// };

// export default someFunction;


/* useEffect 로 초기 한번만 실행 시키기 */
import React, { useState, useEffect } from "react";

const MyComponent = () => {
  const [isValid, setIsValid] = useState({ b: 1 });

  useEffect(() => {
    const currentValid = isValid;
    console.log(currentValid);
    setIsValid({ a: 1 });
  },); // 빈 배열을 사용하여 컴포넌트가 처음 마운트될 때만 실행

  return (
    <div>
      <h1>{JSON.stringify(isValid)}</h1> {/* 객체를 문자열로 변환하여 출력 */}
    </div>
  );
};

export default MyComponent;

 



useRef

DOM 요소나 컴포넌트 인스턴스에 접근하거나, 값이 변경되어도 리렌더링을 트리거하지 않는 변수를 저장하는 React 훅
ex) import React, { useRef, useEffect } from "react";
const 참조변수 = useRef();

 

1. useRef()함수로 참조변수(inputRef) 생성
2. 참조변수(inputRef)를 input 태그의 ref 속성에 대입하여 input 태그의 DOM 요소에 직접 접근을 가능하게 함
3. [입력 필드에 포커스] 버튼 Click 시, focusInput 함수 실행
4. inputRef.current.focus(); 함수로 input 태그에 포커싱

import React, { useRef } from "react";

/* 커서 포커싱 기능 */
const FocusInput = () => {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input ref={inputRef} type="text" placeholder="여기에 입력" />
      <button onClick={focusInput}>입력 필드에 포커스</button>
    </div>
  );
};

/* 파일 업로드 창 기능 */
const FileUploadExample = () => {
  const fileInputRef = useRef();

  const handleButtonClick = () => {
    fileInputRef.current.click();
  };

  return (
    <div>
      <input
        type="file"
        ref={fileInputRef}
        style={{ display: 'none' }}
        accept=".jpg,.png,.jpeg"
      />
      <button onClick={handleButtonClick}>파일 선택</button>
    </div>
  );
};

/* 두 기능을 하나의 화면에서 렌더링하는 부모 컴포넌트 */
const CombinedComponent = () => {
  return (
    <div>
      <h1>기능 통합 예제</h1>
      <FocusInput />
        <h1></h1>
      <FileUploadExample />
    </div>
  );
};

export default CombinedComponent;

 

 


createContext, useContext

createContext : 전역적으로 공유할 수 있는 Context 객체를 생성

userContext : Context API를 통해 제공된 값을 소비하기 위해 사용


ex) import { createContext, useContext } from "react";
const Context객체 = createContext();

  return (

  <Context함수.Provider value={공유할 값}>
    {children}
  </Context함수.Provider>

const 공유할값변수 = useContext( Context객체 );

 

1. createContext()함수로 참조변수(MyContext) 생성

2. MyProvider 함수내에서 Provider 프로퍼티를 이용해 하위 컴포넌트에 데이터를 전달

3. useContext(MyContext) 함수로 컨텍스트 value 획득

4. {children} 특수 프로퍼티로 자식함수의 요소 렌더링

import React, { createContext, useContext } from 'react';

// Context 생성
const MyContext = createContext();

const MyProvider = ({ children }) => {
  const value = "Hello, World!";
  return (
    <MyContext.Provider value={value}>
     {/* children 특수 프로퍼티  */}
      {children}
    </MyContext.Provider>
  );
};

const MyComponent = () => {
  const contextValue = useContext(MyContext);
  return <div>{contextValue}</div>;
};

const App = () => (
  <MyProvider>
    <MyComponent />
  </MyProvider>
);

export default App;

 

 

 


from 'react-router-dom';

Link

React Router에서 사용되는 컴포넌트로, 클라이언트 사이드 네비게이션을 제공하여 페이지를 새로고침하지 않고도 다른 경로로 이동할 수 있게 합니다.

Link는 HTML의 <a> 태그와 유사하게 작동하며, to 속성을 사용하여 URL을 변경함.

ex) import { Link } from "react-router-dom"

<Link to="이동할 경로">Text명</Link>

 

'홈'  Text를 누르면 -> '/' 경로로 이동
'소개' Text를 누르면 -> '/about' 경로로 이

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

function Home() {
  return <h2>홈 페이지</h2>;
}

function About() {
  return <h2>소개 페이지</h2>;
}

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">홈</Link>
            </li>
            <li>
              <Link to="/about">소개</Link>
            </li>
          </ul>
        </nav>

        <Route path="/" exact component={Home} />
        <Route path="/about" component={About} />
      </div>
    </Router>
  );
}

export default App;

NavLink

React Router에서 사용되는 컴포넌트로, 현재 경로와 일치하는 경우 특정 스타일이나 클래스를 적용할 수 있는 Link의 확장 버전
ex) import { NavLink } from "react-router-dom";

<NavLink to="이동할 경로" exact activeClassName="참조할 css 클래스">
    Text명
</NavLink>

 

'홈'  Text를 누르면 -> '/' 경로로 이동
'소개' Text를 누르면 -> '/about' 경로로 이동

차이점은 '홈' 과 '소개' 가 active.css 에서 정의한 대로 UI에 나타난다.

-> NavLink 를 안쓰고 Button 태그와 Link 태그로도 비슷한 기능을 만들 수 있다.

import React from 'react';
import { BrowserRouter as Router, Route, NavLink } from 'react-router-dom';
import './active.css'; // CSS 파일 import

function Home() {
  return <h2>홈 페이지</h2>;
}

function About() {
  return <h2>소개 페이지</h2>;
}

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <NavLink to="/" exact activeClassName="active">
                홈
              </NavLink>
            </li>
            <li>
              <NavLink to="/about" activeClassName="active">
                소개
              </NavLink>
            </li>
          </ul>
        </nav>

        <Route path="/" exact component={Home} />
        <Route path="/about" component={About} />
      </div>
    </Router>
  );
}

export default App;

useParams

React Router에서 사용되는 컴포넌트로, 현재 경로와 일치하는 경우 특정 스타일이나 클래스를 적용할 수 있는 Link의 확장 버전
ex) import { useParams } from "react-router-dom";

const userId = useParams().userId;

 

렌더링 해주는 상위 JS 파일의 경로에서

/:파라미터/aaa/bbb/ccc 인 경우 "파라미터" 부분을 동적으로 useParams().userId; 함수로 리턴해준다.

// // 렌더링 하는 루트 JS 에서 이렇게 UserPlaces 를 렌더링 한다면
// // :userId 에 들어가는 동적인 값이 "useParams().userId;" 여기로 호출 된다.
// <Route path="/:userId/places" exact>
//   <UserPlaces />
// </Route>

const UserPlaces = () => {
  const userId = useParams().userId;
  const loadedPlaces = DUMMY_PLACES.filter(
    place => place.creator === userId
  )
  return (
    <PlaceList items={loadedPlaces} />
  );
};

export default UserPlaces;

 

useHistory

useHistory 훅은 React Router에서 제공하는 훅으로, 컴포넌트 내에서 코드로 Link 경로를 변경 하게 해줌
ex) import { useHistory } from "react-router-dom";

const history = useHistory();

 

1. useHistory 훅을 사용하여 history 객체를 가져옵니다.
2. navigateToHome 함수는 history.push('/home')를 호출하여 사용자를 '/home' 경로로 이동시킵니다.
3. 버튼을 클릭하면 navigateToHome 함수가 실행되어 경로가 변경됩니다.

import React from 'react';
import { useHistory } from 'react-router-dom';

const MyComponent = () => {
  const history = useHistory();

  const navigateToHome = () => {
    // '/home' 경로로 이동
    history.push('/home');
  };

  return (
    <div>
      <h1>현재 페이지</h1>
      <button onClick={navigateToHome}>홈으로 이동</button>
    </div>
  );
};

export default MyComponent;

 

 


from 'react-dom';

ReactDOM

React 컴포넌트를 브라우저의 DOM에 렌더링하고, DOM과의 상호작용을 관리하는 React 라이브러리
ex) import ReactDOM from 'react-dom';

 

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React 예제</title>
</head>
<body>
  <div id="root"></div>
  <script src="index.js"></script>
</body>
</html>

 

import React from 'react';
import ReactDOM from 'react-dom';

function App() {
  return (
    <div>
      <h1>안녕하세요, React!</h1>
      <p>이것은 간단한 React 예제입니다.</p>
    </div>
  );
}

// ReactDOM을 사용하여 App 컴포넌트를 'root' ID를 가진 DOM 요소에 렌더링합니다.
ReactDOM.render(<App />, document.getElementById('root'));

 

 


from 'react-transition-group';

CSSTransition
React 애니메이션 라이브러리인 react-transition-group에서 제공하는 컴포넌트로, 컴포넌트의 마운트 및 언마운트 시 CSS 트랜지션 효과를 쉽게 적용할 수 있다.

CSS라이브러리 설치 방법 : >> npm install react-transition-group

ex) import { CSSTransition } from 'react-transition-group'

<CSSTransition
    in= [in true mountOnEnter 작업, false unmountOnExit 작업]
    timeout= [트랜지션효과(애니메이션)의 지속 시간]
    classNames= [css클래스 효과 지정]
    mountOnEnter
    unmountOnExit
>
    <div>
        <h1>안녕하세요, React!</h1>
    </div>
</CSSTransition>

 

1. CSSTrasition 컴포넌트의 "in" 이라는 속성(props 혹은 요소)이 true 인지 false 인지에 따라, mount unmount 동작을 한다. 

2. 애니메이션이 한번 동작하는데 걸리는 시간 < timeout

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'언어 정리 > React, Nodejs, Express' 카테고리의 다른 글

MongoDB, Mongoose  (0) 2024.10.11
Express  (0) 2024.09.26
NodeJS  (0) 2024.09.26

댓글