useState 와 useRef

2024. 3. 19. 21:11Daily Codig Reminder

GameBoarder

 

import React, { useState } from 'react';
import "./GameBoarder.css"
const initialGameBoard=[
    [null, null, null],
    [null, null, null],
    [null, null, null],
]
// const[gameBoard, setGameBoard] = useState(initialGameBoard);
function GameBoarder() {
    const[gameBoard, setGameBoard] = useState(initialGameBoard);

    function handleSelect (rowIndex, colIndex){
        //1.방법 (베열에 변경사항이 저장되나 동일한 주소값이기 때문에 새롭게 랜더링 안됨..)
      

        //2. 방법2 : 다른 주소값으로 설정하기 때문에 변경을 인식함
            var newGameBoard = [...gameBoard];
            // Update the selected cell with 'x'
            newGameBoard[rowIndex][colIndex] = 'x';
            // Update the state with the new game board
            setGameBoard(newGameBoard);
    }
    console.log("App호출")
    return (
        <div>
            <ol id='game-board'>
{initialGameBoard.map((row,rowIndex)=> (
    <li key={rowIndex}>
<ol>
    {row.map((col, colIndex)=> {
        console.log(col, rowIndex, colIndex);
        return(
            <li key={colIndex}>
                <button
                disabled={col != null}
                onClick={()=> handleSelect(rowIndex, colIndex)}>
{col}
                </button>
            </li>
        )
    })}
</ol>

    </li>
))}

            </ol>
        </div>
    );
}

export default GameBoarder;

reset

 

import React, { useState } from 'react';
import "./GameBoarder.css"

const initialGameBoard = [
  [null, null, null],
  [null, null, null],
  [null, null, null],
];

function GameBoarder() {
  const [gameBoard, setGameBoard] = useState(initialGameBoard);

  function handleSelect(rowIndex, colIndex) {
    // 2. 방법: 새로운 주소값으로 설정하여 변경 감지
    const newGameBoard = [...gameBoard];
    newGameBoard[rowIndex][colIndex] = 'x';
    setGameBoard(newGameBoard);
  }

  function handleReset() {
    var newGameBoard = [...gameBoard];
    newGameBoard.map((row,rowIndex)=>{
        row.map((col,colIndex)=>{
            newGameBoard[rowIndex][colIndex] = null;
            return null;
  });
  return null;
})
setGameBoard(newGameBoard);
  }
  console.log("App ")
  return (
    <div>
      <ol id='game-board'>
        {initialGameBoard.map((row, rowIndex) => (
          <li key={rowIndex}>
            <ol>
              {row.map((col, colIndex) => {
                return (
                  <li key={colIndex}>
                    <button
                      disabled={col != null}
                      onClick={() => handleSelect(rowIndex, colIndex)}
                    >
                      {col}
                    </button>
                  </li>
                );
              })}
            </ol>
          </li>
        ))}
      </ol>
      <button onClick={handleReset}>Reset</button>
    </div>
  );
}

export default GameBoarder;

userid

import { useState } from "react";
export default function App() {
  const[userid, setUserid]= useState("");

  function handleSubmit(event){
    event.preventDefault();
    console.log(userid);
  }
  function handleChange(event){
    setUserid(event.target.value); //입력값을 useState 에 저장
  }
  console.log("app: ", userid);
  return (
    <>
    <h1>input 태그</h1>
    <form onSubmit={handleSubmit} action="target.html">
      아이디:
      <input
      type="text"
      name='userid'
      value={userid}
      onChange={handleChange}
      ></input>
      <input type="submit" value="로그인"></input>
    </form>
    </>

  );
}

userid+passwd

setInputs({...inputs, [event.target.name]:event.target.value}); <<< 자주 씀

 

import { useState } from "react";
export default function App() {
  const [inputs, setInputs]= useState({userid:"", passwd:""});

  function handleSubmit(event){
    event.preventDefault();
    console.log(inputs)
  }
  function handleChanges(event){
   
    setInputs({...inputs, [event.target.name]:event.target.value});
  }

  return (
    <>
    <h1>input 태그</h1>
    <form onSubmit={handleSubmit} action="target.html">
      아이디:
      <input
      type="text"
      name='userid'
      value={inputs.userid}
      onChange={handleChanges}
      ></input>
      비번:
      <input
      type="password"
      name='passwd'
      value={inputs.passwd}
      onChange={handleChanges}
      ></input>
      <input type="submit" value="로그인"></input>
    </form>
    </>

  );
}

two_way_binding_input태그사용

import { useState } from "react";

export default function App() {
  const [num, setNum] = useState({ n: 0 });
  const [step, setStep] = useState(1);

  // const onIncrease = (step) => {
  //   setNumber({ ...number, n: number.n + step });
  // };

  // const onDecrease = () => {
  //   if (number.n - step >= 0) {
  //     setNumber({ ...number, n: number.n - step });
  //   }
  // };

  const StepChange = (step) => {
   setStep(step);
  };
const increment = ( step)=>{
  setNum (num + step);
};
const dcrement = (step) => {
  setNum ( num - step >=0 ? num - step : 0);
};
  console.log("App 호출", num.n);

  return (
    <>
      <h1>state 실습</h1>
      <label htmlFor="stepSelect">Step 선택:</label>
      <select onChange={(e)=> StepChange(parseInt(e.target.value))}>
        <option value={1}>1</option>
        <option value={2}>2</option>
        <option value={3}>3</option>

      </select><br/>
      num: {num.n}<br />
      <button onClick={increment}>+</button>
      <button onClick={dcrement}>-</button><br />
     

    </>
  );
}

 

 

태그와 input 와 동기화로 작성 (name 을 동일하게, value 부분 데이터 출력 코드 ⇒ handleChange inputs 출력으로 정상 저장확인

import React, { useState } from 'react';
import MemberFun from './MemberFun';
function MemberListFun(props) {
    const [memberData, setMemberData]= useState([]);
    const [inputs, setInputs] = useState({
        username:'',
        age:'',
        address:''
      
    });
    const {username, age, address} = inputs;

    const handleChange = (e) => {
        const{name, value}= e.target;
        console.log(name, ":", value);
        setInputs({...inputs, [name]:value});
    };
     const handleSubmit = (e) => {
        e.preventDefault();
        // 여기에 입력값을 memberData에 추가하는 로직을 추가할 수 있습니다.
       var user = {
        username,
        age,
        address
       }
        setMemberData([...memberData, user]);
 setInputs({
            username: '',
            age: '',
            address: ''
        });
       
    };
    return (
        <div>
           <form onSubmit={handleSubmit}>
이름: 
<input
type='text'
name='username'
value={username}
onChange={handleChange}

></input><br/>
나이: 
<input
type='text'
name='age'
value={age}
onChange={handleChange}

></input>   <br/>
주소:
<input
type='text'
name='address'
value={address}
onChange={handleChange}

></input>         <br/>
<button type="submit">추가</button>
</form>
<h2>멤버 목록</h2>
<table border='1'>
                <thead>
                    <tr>
                        <th>이름</th>
                        <th>나이</th>
                        <th>주소</th>
                    </tr>
                </thead>
                <tbody>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                    {memberData.map((member, index) => (
                        <MemberFun key={index} member={member} />
                    ))}
                </tbody>
            </table>
</div>
    );
}

export default MemberListFun;

 

 

import React from 'react';

function MemberFun({ member }) {
    return (
        <tr>
            <td>{member.username}</td>
            <td>{member.age}</td>
            <td>{member.address}</td>
        </tr>
    );
}

export default MemberFun;

 

 

import { useState } from "react";
import MemberListFun from "./components/MemberListFun";

export default function App() {


  return (
    <>
      <MemberListFun></MemberListFun>
     

    </>
  );
}

조건부 렌더링 구현

useState (true) ⇒is editing

if 문사용

홍길동 save 버튼 클릭시 ⇒ handleEvent 호출

textbook edit 버튼으로 변경

 

 

조건부랜더링3가지방법변수3항엔퍼샌트

 

import React, { useState } from 'react';

function App() {
    const [text, setText] = useState('');
    const [isEditing, setIsEditing] = useState(false);

    const handleChange = (e) => {
        setText(e.target.value);
    };

    const handleEvent = () => {
        // 여기에 변경된 값을 처리하는 로직을 추가할 수 있습니다.
        console.log('Saved:', text);
        setIsEditing(false);
    };

    const handleEdit = () => {
        setIsEditing(true);
    };

    return (
        <div>
          <h1>조건부 랜더링 구현볍 1: if문 이용</h1>
    
          <button onClick={handleEvent}> {isEditing ? "save": "Edit"}</button>
          <hr/>
          <h1>조건부 랜더링 구현법 2: 3항연산자 이용</h1>
            {isEditing ? <span>홍길동</span> :<input/>}
            <button onClick={handleEvent}>{isEditing ? "save": "Edit"}</button>
          <h1>조건부 랜더링 구현법 3 : 3ㅏ항연산자 이용</h1>
         {isEditing && <span>홍길동</span>}
         {!isEditing && <input/>}
         <button onClick={handleEvent}>{isEditing ? "save": "Edit"}</button>

        </div>
    );
}

export default App;

 

 

useRef01_state로input관리한경우매번재래더링됨

 

import React, { useState } from 'react';

function Player(props) {
    const [playerName, setPlayerName] = useState('');
    const [submitted, setSubmitted] = useState(false);

    function handleChange (event){
        setPlayerName(event.target.value);
    };

    function handleClick() {
        setSubmitted(true);
    };

    return (
        <div>
            <h1>환영합니다 {submitted ? playerName : "unknown entity"}</h1>
            <input
                type="text"
                value={playerName}
                onChange={handleChange}
            />
            <button onClick={handleClick}>Save</button>
        </div>
    );
}

export default Player;

useRef

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

function Player(props) {
    const playerName = useRef();
    //태그중 ref={playerName}을 참조함
    //////////////////state 와 다르게 값을 변경해도 재랜더링되지않고 ,current 속성을 사용
    const [enterPlayerName, setEnterPlayerName] = useState(null);
    //저장 button 을 클릭 했을 때만 재랜더링 됨, 효율적임

    function handleClick() {
        setEnterPlayerName(playerName.current.value);
       //4) useRef 데이터의 활용
       playerName.current.value="";
    };
console.log("player", playerName)
console.log("player", enterPlayerName)
    return (
        <div>
            <h1>환영합니다 {enterPlayerName ?? "unknown entity"}</h1>
            <input
                type="text"
                ref={playerName}
                
            />
            {/* useref 와 연동*/}
            <button onClick={handleClick}>Save</button>
        </div>
    );
}

export default Player;

forwardRef()

부모 컴포넌트에서 자식 컴포넌트 접근시 ref 속성으로 이용해야 되는데

ref는 일반 Props 로 처리되지 않기 때문에 forwardRef()를 사용하여 자식 컴포넌트를 감싸야 된다.

이렇게 ref 속성을 이용하여 자식 컴포넌트를 참조할 때 사용된다.

 

import React, { useState, useRef } from 'react';
import Box from './components/Box';
function App() {
  const boxRef = useRef();
  function handleEvent(){
    console.log("handleEvent");
    boxRef.current.open();// 자식 box의 메소드 호출 가능
  }
    return(
      <>
      <button onClick={handleEvent}>자식의 open 이벤트 호출</button>
      <Box ref={boxRef}></Box>
      {/* 2) useRef 참조*/}
      </>
    )

}

export default App;

 

 

import React, { forwardRef, useImperativeHandle } from 'react';
const Box = forwardRef((props, ref) =>{
    useImperativeHandle(ref,()=> ({open}));
    const open = ()=> {
        console.log("box.opes()======");
    };

   return 
    <>
    <hr/>
    box component
    <hr/>
    </>
});
export default Box;

'Daily Codig Reminder' 카테고리의 다른 글

useEffect , memo  (0) 2024.03.19
useRef  (0) 2024.03.19
useState, 이벤트, hook  (0) 2024.03.17
props  (0) 2024.03.17
React  (0) 2024.03.17