useRef

2024. 3. 19. 21:25Daily 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