React

react(2)- useState, useRef

두설날 2024. 5. 16. 09:32

*이 글을 읽기전에 작성자 개인의견이 있으니, 다른 블로그와 교차로 읽는것을 권장합니다.*

리액트 Cmder 실행

tools폴더안의 Cmder.exe파일 실행

tools폴더안의 Cmder.exe파일 실행

// 경로 이동
cd 폴더경로
// 폴더 생성
yarn create react-app 폴더이름
// yarn 시작
yarn start

1. useState 함수

useState함수는 동적인 값인 함수로 바꾸는 함수입니다. 매개변수와 콜백함수, 초기값을 정의하고, 이후 component에서 사용할 수 있습니다.

//useState함수
const [매개변수, 콜백함수] = useState();

Counter.js파일에서 +1 / -1 출력하기

import React, {useState} from "react";

function Counter() {
    const [number, setNumber] = useState(0);
    const onIncrease = () => {
        // number++;
        // console.log('+1');
        setNumber(number + 1);
        console.log('+1');
    }
    const onDecrease = () => {
        // number--;
        // console.log('-1');
        setNumber(number - 1);
        console.log('-1');
    }
    return (
        <div>
            <h1>{number}</h1>
            <button onClick={onIncrease}>+1</button>
            <button onClick={onDecrease}>-1</button>
        </div>
    );
}
export default Counter;
// App.js파일
import React from "react";
import Counter from "./Counter"
function App() {
	return (
		<Counter/>
);}
export default App;

2. 입력필드와 초기화버튼 구현

// input.js 파일
import React, {useState} from "react";
function Input() {
    const [text, setText] = useState('');
    // js 이벤트 객체 전달
    const onChange =(e) => {
        setText(e.target.value);
    }
    const onReset = () => {
        setText('');
    }
    return (
        <div>
            <input onChange={onChange} value={text}/>
            <button onClick={onReset}>초기화</button>
            <div>
                <b>값: {text}</b>
            </div>
        </div>
    );
}
export default Input;
// App.js파일
import React from "react";
        import Input from "./Input";
        function App() {
          return (
            <Input/>
          );
        }
export default App;

3. 입력 필드와 초기화 버튼

// MultiInput.js 파일
import React, {useState} from "react";
function MultiInput() {
    // 이벤트 핸들러를 2개를 써도 되지만, useState함수의 매개변수 inputs를-> {userid, name} 2개로 복수 설정
    const [inputs, setInputs] = useState({
        userid: '',
        name: ''
    });
    const {userid, name} = inputs;
    const onChange = (e) => {
        const {value, name} = e.target;
        setInputs ({
            ...inputs,
            [name]: value
        });
    }
    const onReset = () => {
        setInputs({
            userid: '',
            name: ''
        });
    }
    return (
        <div>
            <input placeholder="아이디" name="userid" onChange={onChange} value={userid}/>
            <input placeholder="이름" name="name" onChange={onChange} value={name}/>
            <button onClick={onReset}>초기화하기</button>
            <div>
                <b>값: </b>
                {userid}({name}입니다.)
            </div>
        </div>
    );
}
export default MultiInput;
// App.js 파일
import React from "react";
        import MultiInput from "./MultiInput"

        function App() {
          return (
            <MultiInput/>
          );
        }
        export default App;

4. Counter 활용

문제)

아래와 같은 카운터 프로그램을 작성해보자
- 두 Count의 합이 TotalCount에 표기
- 두 카운트의 숫자는 별개로 함
- TotalCount의 값이 10보다 작으면 👎 출력하고, 10 이상이면 👍를 출력
TotalCount: 0 👎
    0
  [add]
    0
  [add]

// App.css파일
.container {
  width: 600px;
  margin: auto;
}
.banner {
  text-align: center;
  margin-top: 5rem;
  font-size: 2rem;
  background-color: gold;
  font-weight: bold;
}
.counter {
  display: flex; 
  flex-direction: column;
  align-items: center;
  margin: 2rem;
  padding: 1rem;
  border-radius: 1rem;
  border: 2px solid orange;
}
.counter:hover {
  background-color: ivory;
}
.number {
  font-size: 2rem;
}
.button {
  font-size: 2rem;
  padding: 0.2rem, 1rem;
  border-radius: 0.5rem;
  cursor: pointer;
  background-color: yellow;
}
.total {
  font-size: 1rem;
  margin-left: 0.5rem;
}
// Counter.jsx파일
import React, {useState}  from "react";
export default function Counter({ total, onClick}){
    const [count, setCount] = useState(0);
    return (
        <div className='counter'>
            <p className='number'>
                {count} <span className="total">/{total}</span>
            </p>
            <button className="button" onClick={() => {
                setCount((prev) => prev + 1);
                onClick();
            }}>+1</button>
        </div>
    );
}
// App.js -> AppCounter.jsx 파일
import React, {useState} from "react";
import Counter from "./Counter";
import Input from "./input";
import MultiInput from "./MultiInput";
import Count from "./components/Count";
import './App.css';
export default function AppCounter() {
  const [count, setCount] = useState(0);
  const handleClick = () => setCount((prev) => prev +1 );
  return (
    <div className="container">
      <div className="banner">
        Total Count: {count} {count > 10 ? '👍': '👎'}
      </div>
      <div className="counters">
        <Count total={count} onClick={handleClick}/>
        <Count total={count} onClick={handleClick}/>
      </div>
    </div>
  );
}
// index.js파일 수정
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import AppCounter from './AppCounter';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <AppCounter />
  </React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

5. useReft

useRef는 React에서 사용되는 Hook 중 하나입니다. 이 Hook을 사용하면 함수 컴포넌트 내에서 DOM 요소나 다른 값에 대한 참조를 생성할 수 있습니다.   DOM 요소에 직접 접근할 수 있으며, 컴포넌트가 렌더링될 때마다 새로 생성되지 않고 이전에 생성된 참조를 유지할 수 있습니다. 컴포넌트가 마운트되었을 때 해당 DOM요소에 포커스를 설정합니다.

// UserList.js 파일
import React from "react";
function User({user}) {
    return (
        <div>
            <b>{user.username}</b> <span>({user.email})</span>
        </div>
    )
}
function  UserList({users}) {
    
    return (
        <div>
            {
                users.map((user, index) => (
                    <User user={user} key={user.id}/>
                ))
            }
        </div>
    );
}
export default UserList;
// CreateUser.js 파일
import React from "react";
function CreateUser({username, email, onChange, onCreate}) {
    return(
        <div>
            <input name="username" placeholder="아이디" onChange={onChange} value={username}/>
            <input name="email" placeholder="이메일" onChange={onChange} value={email}/>
            <button onClick={onCreate}>등록</button> 
        </div>
    )
}
export default CreateUser;
// App.js파일
import UserList from "./UserList";
import React, {useState, useRef} from "react";
import CreateUser from "./CreateUser";
function App() {
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  });
  const { username, email} = inputs;
  const onChange = e => {
    const {name, value} = e.target;
    setInputs({
      ...inputs,
      [name]: value
    });
  };
  const [users, setUsers] = useState([
    {
      id:1,
      username:'apple',
      email:'apple@apple.com',
  },
  {
      id:2,
      username:'banana',
      email:'banana@banana.com',
  },
  {
      id:3,
      username:'orange',
      email:'orange@orange.com',
  }
  ]);
  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers([...users, user]);

    setInputs({
      username: '',
      email: ''
    });
    nextId.current +=1;
  }
  return (
    <>
      <CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate}/>
      <UserList users={users}/>
    </>
  );
}
export default App;