useRef
2024. 3. 19. 21:25ㆍDaily Codig Reminder
input관리매번랜너링문제해결
import { useState, useRef } from "react"; ////////////////
export default function Player() {
const username = useRef();
const age = useRef();
//태그 중 ref={playerName}을 참조함
////////////////////state와 다르게 값을 변경해도 재랜더링 되지 않고, current 속성을 사용
const [inputs, setEnterdPlayerName] = useState({username:"", age:""});
//button 을 클릭했을 때만 재랜더링 됨 , 효율적임
function handleClick() {
var new_inputs={...inputs, username:username.current.value, age:age.current.value};
console.log(new_inputs);
setEnterdPlayerName(new_inputs)
username.current.value = "";
age.current.value = "";
}
return (
<>
<section id="player">
<p>
<input type="text" name="username" ref={username}></input>
<input type="text" name="age" ref={age}></input>
<button onClick={handleClick}>저장</button>
</p>
</section>
<hr></hr>
{inputs.username}/{inputs.age}
</>
);
}
import Player from "./components/Player";
export default function App() {
return (
<>
<Player></Player>
</>
);
}
자식컴포넌트메서드호출2모달창구현1_App에서구현
import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react';
const Box = forwardRef((props, ref)=>{
//반드시 forwardRef 로 감싸고 ref로 받음
const modal = useRef();
useImperativeHandle(ref, ()=> ({open}))//부모에게 노출
function open(){ //부모가 호출할 함수
modal.current.showModal(); //모달창 띄우기
}
const handleClose = () => {
modal.current.close();
};
return(
<>
<dialog ref={modal}>
<h2>모달창</h2>
<form>
아이디: <input></input>
비번: <input></input>
<button onClick={handleClose}>close</button>
</form>
</dialog>
</>
)
}); //end forwardRef
function App() {
const box = useRef();
function show_modal(){
box.current.open();// 자식 box의 메소드 호출 가능
}
return(
<>
<button onClick={show_modal}>모달창 보기</button>
<Box ref={box}></Box>
{/* 2) useRef 참조*/}
</>
)
}
export default App;
import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react';
import Box from './components/Box'
function App() {
const box = useRef();
function show_modal(){
box.current.open();// 자식 box의 메소드 호출 가능
}
return(
<>
<button onClick={show_modal}>모달창 보기</button>
<Box ref={box}></Box>
{/* 2) useRef 참조*/}
</>
)
}
export default App;
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
import "./Box.css"
const Box = forwardRef((props, ref) => {
const modal = useRef(null);
useImperativeHandle(ref, () => ({
open: () => {
modal.current.showModal();
}
}));
const handleClose = () => {
modal.current.close();
};
return (
<>
<dialog ref={modal} className='result-modal'>
<h2>모달창</h2>
<form>
아이디: <input type="text" />
비번: <input type="password" />
<button type="button" onClick={handleClose}>close</button>
</form>
</dialog>
</>
);
});
export default Box;
.result-modal{
border: none;
border-radius: 8px;
padding: 2rem;
background-color: azure;
}
조건부랜더링시_current참조여부검증필요
import React, { useState, forwardRef, useRef, useImperativeHandle } from 'react';
function App() {
const inputRef= useRef();
const [showText, setShowText] = useState(false);
const boxRef = useRef(null);
return (
<>
{showText && <input type='text' ref={inputRef}/>}
<button onClick={()=> setShowText(()=> !showText)}>텍스트 박스 {showText ? '숨기기' : '보이기'}</button>
<hr/>
{/*다음 버튼은 위의 버튼이 보이는 경우에만 동작, 가리기된경우 에러 발생*/}
<button onClick={()=> inputRef.current.focus()}>
텍스트 1로 이동 에러
</button>
{/*다음 버튼은 가리기 된경우에도 에러가 발생하지 않는다 */}
<button onClick={()=> inputRef.current && inputRef.current.focus()}>
텍스트로 이동
</button>
<button onClick={()=> showText && inputRef.current.focus()}>
텍스트로 이동3
</button>
</>
);
}
export default App;
useContext01적용안된_prop_drilling상태
import React, { useState, forwardRef, useRef, useImperativeHandle } from 'react';
import Profile from './components/Profile'
function App() {
const [username, setUsername] = useState('Mike');
return (
<>
<Profile username={username} />
</>
);
}
export default App;
import React, { useState } from 'react';
import Greeting from './Greeting'
function Profile({ username }) {
return (
<div>
<Greeting username={username} />
</div>
);
}
export default Profile;
import React from 'react';
function Greeting({username}) {
return (
<div>
<p>greeting: {`${username}님 안녕하세요`}</p>
<p>greeting: {username}님 안녕하세요</p>
</div>
);
}
export default Greeting;
useContext적용
import React, { useState} from 'react';
import Profile from './components/Profile'
import { UserContext } from './store/user-context';
function App() {
const [username, setUsername] = useState('Mike');
return (
<>
<UserContext.Provider value={username}>
<Profile />
</UserContext.Provider>
</>
);
}
export default App;
import React, { useState } from 'react';
import Greeting from './Greeting'
function Profile({ username }) {
return (
<div>
<Greeting username={username} />
</div>
);
}
export default Profile;
import React from 'react';
import { useContext } from 'react';
import { UserContext } from '../store/user-context';
function Greeting() {
const username = useContext(UserContext);
return (
<div>
<p>greeting: {`${username} provider 에서 받음`}</p>
</div>
);
}
export default Greeting;
import React, { createContext } from 'react';
export const UserContext = createContext("");
하위컴포넌트에서cart저장및출력
import React, { useState} from 'react';
import { CartContext } from './store/cart-context';
import CartModel from './components/CartModel'
function App() {
const [shoppngCart, setShoppingCart] = useState([]);
function handleAddItemCart(cart){
console.log(cart);
setShoppingCart([...shoppngCart, cart]);
}
return (
<>
<CartContext.Provider value={shoppngCart}>
<CartModel onAddToCart={handleAddItemCart}/>
</CartContext.Provider>
</>
);
}
export default App;
import { createContext } from "react";
export const CartContext = createContext("");
import React, { useContext } from 'react';
import { CartContext } from '../store/cart-context';
function Cart() {
const cartItems = useContext(CartContext);
return (
<div>
<h2>Shopping Cart</h2>
<ul>
{cartItems.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default Cart;
import React, { useRef } from 'react';
import Cart from './Cart';
function CartModel({ onAddToCart }) {
const cartRef = useRef();
return (
<div>
car:
<input
type="text"
ref={cartRef}
/>
<button onClick={()=> onAddToCart(cartRef.current.value)}>Add to Cart</button>
<hr/>
<Cart/>
</div>
);
}
export default CartModel;
import React, { useState} from 'react';
import { CartContext } from './store/cart-context';
import CartModel from './components/CartModel'
function App() {
const [shoppngCart, setShoppingCart] = useState([]);
const ctxValue={
items: shoppngCart,
addItemToCart: handleAddItemCart,
}
function handleAddItemCart(cart){
console.log(cart);
setShoppingCart([...shoppngCart, cart]);
}
return (
<>
<CartContext.Provider value={ctxValue}>
<CartModel onAddToCart={handleAddItemCart}/>
</CartContext.Provider>
</>
);
}
export default App;
import { createContext } from "react";
export const CartContext = createContext("");
import React, { useContext } from 'react';
import { CartContext } from '../store/cart-context';
function Cart() {
const { items } = useContext(CartContext);
return (
<div>
<h2>Shopping Cart</h2>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default Cart;
import React, { useRef, useContext } from 'react';
import { CartContext } from '../store/cart-context';
import Cart from './Cart';
function CartModel() {
const cartRef = useRef();
const { addItemToCart } = useContext(CartContext);
return (
<div>
car:
<input
type="text"
ref={cartRef}
/>
<button onClick={()=> addItemToCart(cartRef.current.value)}>Add to Cart</button>
<hr />
<Cart />
</div>
);
}
export default CartModel;
Provider멀티설정
import React, { createContext, useContext, useState } from 'react';
// UserContext 생성
const UserContext = createContext("unknown");
const ThemeContext = createContext("dark");
const Profile = ()=>{
console.log("Profile")
return <Greeting></Greeting>
}
const Greeting = ()=>{
const theme = useContext(UserContext);
const username =useContext(ThemeContext);
console.log("theme: ", theme, "username: " , username);
return (
<>
<p style={{color: theme ==="dark" ? "grey":"green"}}>
{`${username}님 안녕하세요?`}
</p>
</>
)
}
function App() {
const [name, setName] = useState("mike2");
return (
<>
<ThemeContext.Provider value={'light'}>
<UserContext.Provider value={name}>
<div>상단메뉴</div>
<Profile/>
<div>하단메뉴</div>
</UserContext.Provider>
</ThemeContext.Provider>
</>
);
}
export default App;
import React, {useReducer } from 'react';
/*
상태관리 방법
가. useState
나.useReducer: 컴포넌트와 상태 업데이트 로직을 분리 가능하도록 구현이 가능
- 아키텍쳐
액션 => 리듀서 => 상택ㅄ(state)
<===== 뷰(이벤트 발생) <====
1. reducer 는 현재값인 state 와 action 인자를 받아서 새로운 newstate 값을 반환함
import {useReducer } from 'react';
const reducer = (state, action)=>{
return nextState;
}
2. action의 형태는 다음과 같으며 dispath 함수로 전달한다
{
type: 'INCRECEMEMT'
}
{
type:'CHANGE_INPUT',
key: 'email',
value:'zzz@naver.com'
}
{
type:'ADD_TODO',
todo:{
id:1,
pw:2
}
//////
실제 사용방법은 다음과 같다
const [state , dispath] = useReducer (reduce, initialState);
const onIncrease = (){
dispath ({type:'INCRECEMENT});
};
}
*/
export default function App() {
const reducer = (current_state, action) => {
switch (action.type){
case "INCRECEMENT":
console.log("increcement");
return(current_state = current_state+1);
case "DECRECEMENT":
console.log("Decrecement");
return (current_state = current_state -1);
default :
console.log("default");
return current_state;
}
};
//////////////////////////////////
const [number, dispath] = useReducer(reducer,0);// 순서 주의
const onIncrease = ()=> {
//기존방식
//number= number+1
//setNumber(number)
dispath({type: "INCRECEMENT"});
};
const onDecrease = ()=>{
dispath({type: "DECRECEMENT"});
};
return (
<>
<h1>{number}</h1>
<button onClick={onIncrease}>+</button>
<button onClick={onDecrease}>-</button>
</>
);
}
import React, { useReducer, useRef, useState } from 'react';
// 리듀서 함수
export default function App() {
const reducer = (current_state, action) => {
switch (action.type) {
case "ADD":
return [...current_state, action.xxx];
case "DEL":
return [current_state.filter((v,i) => v !== action.xxx)]; // 동일한 아이템 모두 삭제
default:
return current_state;
}
};
const [item, setItem] = useState("");
const [items, dispatch] = useReducer(reducer, []);
// 추가 버튼 클릭 시 항목 추가
const onIncrease = () => {
dispatch({ type: "ADD", xxx: item });
};
// 삭제 버튼 클릭 시 동일한 항목 모두 삭제
const onDecrease = () => {
dispatch({ type: "DEL", xxx: item });
};
console.log("items: ", items);
function handleChange(event){
setItem(event.target.value);
}
return (
<>
<input type='text' value={item} onChange={handleChange}></input>
<button onClick={onIncrease}>추가</button>
<button onClick={onDecrease}>삭제</button>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</>
);
}
'Daily Codig Reminder' 카테고리의 다른 글
axios, router (0) | 2024.03.24 |
---|---|
useEffect , memo (0) | 2024.03.19 |
useState 와 useRef (0) | 2024.03.19 |
useState, 이벤트, hook (0) | 2024.03.17 |
props (0) | 2024.03.17 |