• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 컴포넌트내 함수관련 질문드립니다.

컴포넌트내 함수관련 질문드립니다.

2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 글쓴이
  • #109858

    문세웅
    참가자
    컴포넌트에서 이벤트 핸들러를 추가할 때, 그 함수에서 state값을 사용해야하면 순수함수형태로는 구현이 어려운가요 ?
    props든 state든 함수내에서 쓰이는값은 인자로 전달받아서 사용하고싶은데 테스트해보니 구현이 잘 안되는 것 같아서 질문 드립니다.
    작년 추석때쯤 강의 듣고 그 후에 리액트로 코드를 안짜봐서 기억이 가물가물하지만...급하게 리액트 코드 리뷰할 일이 있어서 질문드립니다.
    쇼핑몰 강의때 작성했던 상세페이지 코드에 eventTest 함수 추가해서 countState를 인자로전달해 출력해보니 false가 나오네요...  
    이벤트 핸들러 작성할때 state는 무조건 직접참조를 해야하는건지, 순수함수의 조건중에 하나가 외부의 값을 조작하거나 참조하지 않는걸로 알고있는데
    리액트의 이벤트핸들러에서 state를 참조할때는 어쩔수 없는 부분인지도 궁금합니다.
    추천하는 방식도 있으시면 알려주시면 도움이 될 것 같습니다.
    
    
    ```detail_page.js
    </pre>
    <pre>import { useContext, useEffect, useState } from "react";
    import { Nav } from "react-bootstrap";
    import { useDispatch, useSelector } from "react-redux";
    import { useParams } from "react-router-dom";
    import styledComponents from 'styled-components';
    import {Context1} from './App';
    import {addItem} from './store';</pre>
    <pre>function DetailPage(props) {
    let context = useContext(Context1);
    // let {context} = useContext(Context1);
    console.log('context: ');
    console.log(context);</pre>
    <pre>useEffect(()=> {
    setTimeout(()=>{
    setSaleButtonState(false);
     }, 2000)
    // useEffect 실행 조건을 넣을 수 있는 곳은 []</pre>
    <pre>// useEffect 동작 전에 실행되는 코드는 return() => { 이안에 }
    // return() => { } 코드 (clean up function)는 mount시 실행 안되고 unmount시 실행됨
     }, [])</pre>
    <pre> 
    let { id } = useParams();
    let item = props.shoes.find((element) => element.id === id);
    let imageSerial = parseInt(id) + 1;
    let [saleButtonState, setSaleButtonState] = useState(true);
    let [countState, setCountState] = useState('');
    let [tab, setTabState] = useState(0);
    let [animation, setAnimation] = useState('');
    let dispatch = useDispatch();
    let cartData = useSelector((state)=>state.cartData);
     
    useEffect(() => {
    let watchedItems = JSON.parse(localStorage.getItem('watched'));
    if (!watchedItems.includes(id)) {
    localStorage.removeItem('watched');
    watchedItems.push(id);
    // watchedItems = new Set(watchedItems);
    // watchedItems = Array.from(watchedItems);
    localStorage.setItem('watched', JSON.stringify(watchedItems));
     }
     }, [id]);</pre>
    <pre>let YelloBtn = styledComponents.button`
     background: ${ props => props.bg };
     color: ${ props => props.bg == 'blue' ? 'white' : 'black'};
     padding: 10px;
     `;
    // let newBtn = styledComponents.button(YelloBtn) YelloBtn의 스타일을 복사해서 사용함
    useEffect(() => {
    let timer = setTimeout(() => {
    setCountState(false)
     }, 1000)
    return () => {
    clearTimeout(timer);
     }
     }, [countState])</pre>
    <pre>useEffect(()=> {
    // 리액트의 automatic batching 기능 때문에 타이머가 필요함.
    // automatic batching: 가까운곳에 state를 변경하는 코드가 여러개 있으면 합쳐서 한번에 실행함.
    let timer2 = setTimeout(()=> {
    setAnimation('end');
     }, 100);</pre>
    <pre>return ( ) => {
    setAnimation('');
    clearTimeout(timer2);
     }
     }, [])</pre>
    <pre>function eventTest(_countState)
     {
    console.log(_countState);
     }</pre>
    <pre>return(
    <div className={'container start ' + animation}>
    {
    saleButtonState ? <div className="alert alert-warning">2초이내 구매시 할인</div> : null
    }
    <YelloBtn bg="blue">버튼</YelloBtn>
    <YelloBtn bg="orange">버튼</YelloBtn>
    {/* 장바구니 목록{ JSON.stringify(cartData)} */}
    <div className="row">
    <div className="col-md-6">
    < img src={"https://codingapple1.github.io/shop/shoes" + imageSerial + ".jpg"} width="100%" />
    </div>
    <div className="col-md-6">
    {
    isNaN(countState) ? <div className="alert alert-warning">경고: 숫자만 입력하세요.</div> : null
    }
    <input className="input count" onInput={(e)=>{
    setCountState(e.target.value)
     }}></input>
    <h4 className="pt-5">{props.shoes[id].title}</h4>
    <p>{props.shoes[id].content}</p>
    <p>{props.shoes[id].price}원</p>
    <button className="btn btn-danger" onClick={()=> {
    dispatch(addItem(props.shoes[id]))
    // console.log(props.shoes[id]);
     }}>장바구니 담기</button>
    <button className="btn btn-danger">주문하기</button>
    </div>
    <Nav variant="tabs" defaultActiveKey="link0">
    <Nav.Item>
    <Nav.Link eventKey="link0" onClick={()=>{eventTest(countState)}}>버튼0</Nav.Link>
    </Nav.Item>
    <Nav.Item>
    <Nav.Link eventKey="link1" onClick={()=>{setTabState(1)}}>버튼1</Nav.Link>
    </Nav.Item>
    <Nav.Item>
    <Nav.Link eventKey="link2" onClick={()=>{setTabState(2)}}>버튼2</Nav.Link>
    </Nav.Item>
    </Nav>
    <TabContent tab={tab} shoes={props.shoes}/>
    </div>
    </div>
     )
    }</pre>
    <pre>
    function TabContent(props) {
    /**
     * props가 여러개면 컴포넌트 파라미터를 {props1, props2, props3} 으로 하고 사용가능
     */
    let [fade, setFade] = useState('');
    let shoes = props.shoes;
    console.log('shoes: ');
    console.log(shoes);
    useEffect(()=> {
    // 리액트의 automatic batching 기능 때문에 타이머가 필요함.
    // automatic batching: 가까운곳에 state를 변경하는 코드가 여러개 있으면 합쳐서 한번에 실행함.
    let timer = setTimeout(()=> {
    setFade('end');
     }, 100);</pre>
    <pre>return ( ) => {
    setFade('');
    clearTimeout(timer);
     }
     }, [props.tab])</pre>
    <pre> {if (props.tab == 0) {
    return <div className={'start ' + fade}>내용0</div>
     } else if (props.tab == 1) {
    return <div className={'start ' + fade}>내용1</div>
     } else if (props.tab == 2) {
    return <div className={'start ' + fade}>내용2</div>
     }}
    }</pre>
    <pre>export default DetailPage;</pre>
    <pre>```
    #109877

    codingapple
    키 마스터
    버튼누르면 state수정해야하는데 그걸 pure function으로 구현하는건 불가능할듯요 
    
    
2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관, 개인정보처리방침
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠