관리 메뉴

java,javascript,android,php,sql,공부용,메모용

React 설치 및 기본 컴포넌트 생성, 상태 관리 (useState, useEffect), Props를 이용한 데이터 전달, 이벤트 핸들링 본문

javascript, jQuery & Node.js/React

React 설치 및 기본 컴포넌트 생성, 상태 관리 (useState, useEffect), Props를 이용한 데이터 전달, 이벤트 핸들링

yy_dd2 2024. 8. 2. 14:04
반응형

 

 

React 작동 방식
React는 컴포넌트 기반의 라이브러리로, 사용자 인터페이스(UI)를 구축하기 위해 설계되었습니다. React 애플리케이션은 여러 개의 컴포넌트로 구성되며, 이 컴포넌트들은 상호작용하고 상태를 관리하여 동적인 웹 페이지를 만듬

주요 개념:
컴포넌트: React의 핵심 단위로, UI의 한 부분을 정의합니다. 컴포넌트는 JavaScript 함수 또는 클래스로 작성된다. React의 기본 빌딩 블록으로, UI를 구성하는 독립적인 조각
Props: 컴포넌트에 데이터를 전달하는 방법입니다. 부모 컴포넌트가 자식 컴포넌트에 값을 전달 (부모 컴포넌트가 자식 컴포넌트에 데이터를 전달하는 방법)
State: 컴포넌트 내부에서 관리되는 데이터입니다. 상태는 컴포넌트가 동적으로 업데이트될 때 사용 ( 컴포넌트의 내부 상태를 관리합니다. 상태가 변경되면 컴포넌트는 다시 렌더링)
Hooks: 함수형 컴포넌트에서 상태와 라이프사이클 기능을 사용할 수 있게 해주는 React의 기능 (useState, useEffect 등).
  useState: 함수형 컴포넌트에서 상태를 관리하기 위한 훅
  useEffect: 함수형 컴포넌트에서 부수 효과(예: 데이터 가져오기, DOM 업데이트 등)를 처리하기 위한 훅
React Router: React 애플리케이션에서 페이지 간의 내비게이션을 처리하는 라이브러리

리액트 컴포넌트의 상호작용
App.js: 애플리케이션의 전체적인 구조를 설정 라우팅 설정 및 전체적인 레이아웃을 관리
TodoList.js: Todo 항목 목록을 표시하고, 데이터를 가져오고, 상태를 관리
TodoItem.js: 개별 Todo 항목을 표시하고, 클릭 이벤트를 처리

-------
프로젝트 구조
my-react-app/

├── public/
│   └── index.html       # HTML 템플릿

├── src/
│   ├── components/      # React 컴포넌트들
│   │   ├── TodoList.js  # Todo 목록을 표시하는 컴포넌트
│   │   └── TodoItem.js  # 개별 Todo 항목을 표시하는 컴포넌트
│   │
│   ├── App.js           # 애플리케이션의 루트 컴포넌트
│   └── index.js         # 애플리케이션의 진입점

├── package.json         # 프로젝트 메타데이터 및 의존성
└── README.md            # 프로젝트 설명

----------
React의 동작 방식

 

더보기

React의 동작 방식

Components: React의 애플리케이션은 여러 개의 컴포넌트로 구성. 각 컴포넌트는 UI의 일부분을 정의
useEffect: 컴포넌트가 마운트될 때, 업데이트될 때, 언마운트될 때 특정 작업을 수행

 

상호작용 예시:
App.js에서 라우팅을 설정하고, TodoList와 About 컴포넌트를 정의
TodoList 컴포넌트는 useState와 useEffect를 사용하여 Todo 항목을 상태로 관리하고, API 호출을 통해 데이터를 가져옴
TodoItem 컴포넌트는 개별 Todo 항목을 렌더링하고, 클릭 이벤트를 통해 상태를 변경
이렇게 React의 구성 요소와 상태 관리, 이벤트 처리 등을 이해하고 적용하여 애플리케이션을 구축

1. State  =>  TodoList.js
State는 React 컴포넌트의 내부 상태를 관리. 상태는 컴포넌트의 데이터와 관련된 정보를 저장하며, 이 데이터가 변경되면 컴포넌트는 자동으로 다시 렌더링

State의 정의와 사용:
const [todos, setTodos] = useState([]);는 todos라는 상태 변수를 선언하고, 초기값을 빈 배열로 설정
setTodos는 이 상태를 업데이트할 수 있는 함수
useState를 사용하여 todos 상태를 관리하며, 이 상태는 Todo 항목의 목록을 저장

상태 변경:
toggleTodo 함수에서 상태를 업데이트합니다. 이 함수는 Todo 항목의 완료 상태를 토글하고, setTodos를 사용하여 상태를 갱신
setTodos(todos.map(todo => (todo._id === id ? updatedTodo : todo)));는 상태를 업데이트하여 UI를 다시 렌더링

 
2. Props   =>  TodoItem.js
부모 컴포넌트 (TodoList.js)에서 TodoItem 컴포넌트로 Props 전달:  </todoitem key={todo._id} todo={todo} toggletodo={toggletodo} >

Props의 정의와 사용:
TodoItem 컴포넌트는 todo와 toggleTodo 두 개의 props를 받습니다.
todo는 현재 Todo 항목의 정보를 담고 있으며, toggleTodo는 Todo 항목의 완료 상태를 토글하는 함수

Props를 통해 데이터 전달:
TodoItem 컴포넌트는 부모 컴포넌트(TodoList)에서 받은 todo와 toggleTodo를 사용하여 UI를 렌더링하고, 클릭 이벤트를 처리
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}는 todo.completed에 따라 스타일을 설정
onClick={() => toggleTodo(todo._id)}는 클릭 시 부모 컴포넌트에서 전달받은 toggleTodo 함수를 호출하여 상태를 변경


State는 컴포넌트의 내부 상태를 관리하며, 상태가 변경되면 컴포넌트는 자동으로 다시 렌더링
Props는 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달하는 방법으로, 자식 컴포넌트에서 읽기 전용으로 사용


보안 취약점 해결

보안 취약점을 해결하기 위해 아래 명령
npm audit fix
보안 취약점을 해결하지 못하는 경우 강제로 모든 문제를 해결
npm audit fix --force

 


├── src/
│   ├── components/      # React 컴포넌트들
│   │   ├── TodoList.js  # Todo 목록을 표시하는 컴포넌트
│   │   └── TodoItem.js  # 개별 Todo 항목을 표시하는 컴포넌트
│   │
│   ├── App.js           # 애플리케이션의 루트 컴포넌트

 

components/TodoList.js

더보기
//TodoList 컴포넌트 생성
//import { response } from "express";
// React에서 상태 관리 (useState, useEffect)
import React, { useState, useEffect } from "react";
//Props를 이용한 데이터 전달 및 이벤트 핸들링
import TodoItem from './TodoItem';

// TodoList 컴포넌트: Todo 항목 목록을 표시하는 컴포넌트
function TodoList() {
    // const todos = [
    //     { id : 1, title: 'Learn React', completed: false},
    //     { id: 2, title: 'Build a Todo App', completed: false},
    // ];
    // useState 훅을 사용하여 상태를 정의합니다.
    // todos 상태는 Todo 항목 배열을 저장합니다.
    // useState
    const [todos, setTodos] = useState([
        { id: 1, title: 'Learn React', completed: false },
        { id: 2, title: 'Build a Todo App', completed: false},
        { id: 3, title: '33333', completed: false},
        { id: 4, title: '4444', completed: false},
    ]);
    //const [todos, setTodos] = useState([]);

    // useEffect 훅을 사용하여 컴포넌트가 마운트될 때와 업데이트될 때 특정 작업을 수행합니다.
    // 여기서는 컴포넌트가 처음 마운트될 때 Todo 항목을 API에서 가져옵니다.
    useEffect(() => {
        fetch('/middleware-api/todos', {
            headers: {
                'x-auth-token': '1',    // 테스트용 토큰
            },
        })
        .then(response => response.json())
        .then(data => setTodos(data)) // API에서 받은 데이터를 todos 상태로 설정합니다.
        .then(error => console.error('Error fetching todos:', error));
    }, []); // 빈 배열을 두 번째 인수로 전달하여 컴포넌트가 마운트될 때만 이 효과를 실행합니다.
    // Todo 목록을 렌더링합니다.

    // Props를 이용한 데이터 전달 및 이벤트 핸들링
    // 1. TodoList 컴포넌트 
    // todo 항목의 완료 상태를 토글하는 함수
    const toggleTodo = async (id) => {
        const todo = todos.find(todo => todo._id === id);
        const updatedTodo = { ...todo, completed: !todo.completed };

        try {
            await fetch(`/middleware-api/todos/${id}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'x-auth-token': '1',
                },
                body: JSON.stringify(updatedTodo),
            });

            // 상태를 업데이트하여 UI를 갱신합니다.
            setTodos(todos.map(todo => (todo._id === id ? updatedTodo :todo)));
        } catch (error){
            console.error('Error updating todo', error);
        }
    };
    return (
        <ul>
            {todos.map(todo => (
                <TodoItem key={todo._id} todo={todo} toggleTodo={toggleTodo} />
            ))}
        </ul>
    )
    // return (
    //     <ul>
    //         {todos.map(todo => (
    //             <li key={todo.id}>
    //                 {todo.title}
    //             </li>
    //         ))}
    //     </ul>
    // )
}

export default TodoList;

/*
useState와 useEffect  동작 설명
useState : React 훅으로, 상태 변수를 선언하고 그 상태를 갱신하는 함수를 반환합니다.
예를들어, 'const [todos, setTodos] = useState([]);'는 'Todos'라는 상태 변수를 빈배열로 초기화하고 'setTodos' 함수를 통해 이 상태를 업데이트 할 수 있게 합니다.
useEffect : 컴포넌트가 마운트 업데이트, 언마운트될 때 특정 작업을 수행할 수 있도록 하는 React 훅입니다. 예를 들어, 'useEffect(() => { / * 작업* / }, []);' 는 컴포넌트가 처음 마운트될 때 한 번만 실행되는 작업을 정의합니다. 빈 배열'[]'을 두 번째 인수로 전달하면 마운트될 때만 실행됩니다.
*/

 

components/TodoItem .js

더보기
import React from 'react';

// TodoItem 컴포넌트: 단일 Todo 항목을 표시하는 컴포넌트
// function TodoItem({ todo }) {
//     return <li>{todo.title}</li>;
// }

//Props를 이용한 데이터 전달 및 이벤트 핸들링 컴포넌트에 새로 추가로 인해 클릭 이벤트 핸들링 추가하기
function TodoItem({ todo, toggleTodo}){
    return (
        <li
            style={ { textDecoration: TodoItem.completed ? 'line-through' : 'none' }}
            onClick={ () => toggleTodo(todo._id)}
        >
        {todo.title}
        </li>
    );
}

export default TodoItem;

 

App.js

더보기
// 라우팅 설정
import React from 'react';
//import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; // Routes와 Route 임포트
import TodoList from './components/TodoList';
import About from './components/About';

function App() {
  return (
    <Router>
      <div className='App'>
        <header className='App-header'>
          <h1>Todo App</h1>
          <Routes> {/* Switch 대신 Routes 사용 */}
            <Route path='/' element={<TodoList />} /> {/* Component 대신 element 사용 */}
            <Route path='/about' element={<About />} /> {/* Component 대신 element 사용 */}
          </Routes>
        </header>
      </div>
    </Router>
  )
}
/*
Router: 애플리케이션에 라우팅 기능을 추가합니다.
Switch: Route를 감싸며, 경로에 따라 적절한 컴포넌트를 렌더링합니다.
Route: 특정 경로에 대해 어떤 컴포넌트를 렌더링할지 정의합니다.
*/
export default App;

// import React from 'react';
// import TodoList from './components/TodoList';
// App 컴포넌트: 전체 애플리케이션을 감싸는 컴포넌트
// function App() {
//   return (
//     <div className='App'>
//       <header className='App-header'>
//         <h1>Todo List</h1>
//         <TodoList />
//       </header>
//     </div>
//   );
// }

// export default App;

// import logo from './logo.svg';
// import './App.css';

// App 컴포넌트: 전체 애플리케이션을 감싸는 컴포넌트
// function App() {
//   return (
//     <div className="App">
//       <header className="App-header">
//         <img src={logo} className="App-logo" alt="logo" />
//         <p>
//           Edit <code>src/App.js</code> and save to reload.
//         </p>
//         <a
//           className="App-link"
//           href="https://reactjs.org"
//           target="_blank"
//           rel="noopener noreferrer"
//         >
//           Learn React
//         </a>
//       </header>
//     </div>
//   );
// }

// export default App;
반응형
Comments