useState 와 useRef
2024. 3. 19. 21:11ㆍDaily 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 |