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

home2 게시판 React 게시판 CSSTransition 질문입니다.

CSSTransition 질문입니다.

  • 이 주제에는 4개 답변, 2명 참여가 있으며 codingapple4 년 전에 전에 마지막으로 업데이트했습니다.
5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 글쓴이
  • #10144

    강성구
    참가자

    /*eslint-disable*/
    import axios from 'axios';
    import React, { useContext, useEffect, useState } from 'react';
    import { useHistory, useParams } from 'react-router';
    import { Navbar, Nav, NavDropdown, Jumbotron, TabContent } from "react-bootstrap";
    /* 컴포넌트 파일 만들때는 import React 꼭 해야한다!! */
    // useEffect작성과 동시에 import 자동완성됨
    import styled from 'styled-components';
    import './Detail.scss';
    import {재고context} from './App.js';

    import { CSSTransition } from "react-transition-group";

    // styled-component
    // 컴포넌트에 직접 스타일 넣어서 스타일링하기
    // css를 입혀놓은 컴포너트를 만들어서 쓴다(className 작명 필요없음)
    let 박스 = styled.div'
      padding : 20px;
    ';

    let 제목 = styled.h4'

      font-size: 25px;
      color : ${ props => props.색상 };
    ';

    function Detail(props) {

      let

    = useState(true);
      let [inputData, inputData변경] = useState('');
      let 재고 = useContext(재고context); // value에 해당하는 state를 재고라는 변수에 할당
      // inputData라는 state가 변경이 되면 이 해당 컴포넌트가 재렌더링됨(전문용어로 update된다)
      // 재렌더링될때마다 useEffect도 실행됨

        // useEffect가 실행되는 상황
        // 1. 컴포넌트가 mount 됐을때,
        // 2. 컴포넌트가 update 될 때, 특정코드를 실행할 수 있음
        //                                             ★★★ ★★★★★★★★★ ★★★
        // Detail 컴포넌트 등장하자마자 useEffect 함수 ★★★ 무조건 1번은 수행 ★★★
        //                                             ★★★ ★★★★★★★★★ ★★★
      

      let [누른탭, 누른탭변경] = useState(0);
      let [스위치, 스위치변경] = useState(false);
        useEffect(() => { 

          axios.get();

        // Detail 컴포넌트가 화면에 보일때(랜더링될 때), 또는 업데이트 될때 useEffect 실행됨
          const 타이머 = setTimeout(() => { alert변경(false) }, 2000);
          console.log('무조건 한번 실행');
          // 타이머를 삭제하고 싶을 때를 위해 변수에 저장해서 사용
          // return function () => { 실행코드 }. Detail 컴포넌트가 사라질때(Unmount될때) 실행할 코드.
          // return 해석 : 퉤 뱉는다 의미가 아니라, 오른쪽의 코드를 실행하달라.
           return function() { clearTimeout(타이머) }
        },

    );
        
        // useEffect 여러번 작성 가능. 수행순서는 하향식  

      let history = useHistory();
      let  {id}  = useParams();  /* object 자료형이 남음. {사용자가 입력한 URL파라미터들} */  
      let 찾은상품 = props.shoes.find( x => x.id === Number(id)); /* 타입 맞춰줘야함 */
      
      return(
        <div className="container">
          <박스>{/* styled component */}
            <제목 className="red"> Detail </제목>
            {/* <제목 색상="blue">Detail</제목>
            <제목 색상={"red"}>Detail</제목> */}
          </박스>

          <div style={{ padding:"15px" }}> { inputData }  </div>
          <input onChange={(e) => { inputData변경(e.target.value)}}/> {/* input에 입력된값 */}

          {/* UI 제작 끝  */}
          {/* 항상 보이는 UI가 아니라면 삼항연산자로 켜졌다 꺼졌다 스위치처럼 만드는게 관습!! */}
          {/* useState의 alert변수를 사용하기 위해 {} 써줘야함 */}

            {
              alert === true  
              ? <div className="my-alert"> {/* 쌩 HTML을 넣어줄수있다. 전에는 컴포넌트를 넣었었는데 */}
                  <p>재고가 얼마 남지 않았습니다.</p>
                </div>
              : null
            }
          

          <div className="row">
            <div className="col-md-6">
              <img src={"https://codingapple1.github.io/shop/shoes"+(parseInt(id)+1)+".jpg"} width="100%" />
            </div>
            <div className="col-md-6 mt-4">
              <h4 className="pt-5">{찾은상품.title}</h4>
              <p>{찾은상품.content}</p>
              <p>{찾은상품.price}</p>
              <Info 재고={props.재고} shoes={props.shoes}></Info>

              <button className="btn btn-danger" onClick={ () => {
                let new재고 = [...props.재고];
                new재고[0] > 0 ? new재고[0] -= 1 : new재고[0] = 0
                props.재고변경(new재고);
              }}> 주문하기 </button> 
              <button className="btn btn-danger" onClick={ () => {
                  history.goBack(); // 1. useHistory 라는 훅 import. 2. useHistory() 훅 사용
                  // history.push('/'); push 써서 특정경로로 이동.
              }}> 뒤로하기 </button> 
            </div>
          </div>

          {/* 부트스트랩 Tab만들기 복붙 */}
          <Nav className="mt-5" variant="tabs" defaultActiveKey="link-1">{/* mt : 부트스트랩이 기본제공하는class margin-top-5 */}
            <Nav.Item>
              <Nav.Link eventKey="link-0" onClick={ () => { 누른탭변경(0), 스위치변경(false) }}>Active</Nav.Link>
            </Nav.Item>
            <Nav.Item>
              <Nav.Link eventKey="link-1" onClick={ () => { 누른탭변경(1), 스위치변경(false) }}>Option 1</Nav.Link>
            </Nav.Item>
            <Nav.Item>
              <Nav.Link eventKey="link-2" onClick={ () => { 누른탭변경(2), 스위치변경(false) }}>Option 2</Nav.Link>
            </Nav.Item>
          </Nav>
          
          {/* 삼항연산자는 3개이상의 조건이 있을때 좋은게 아니다. */}
          {/* {
            누른탭 == 0
            ? <div>00</div>
            : <div>11</div>    
          } */}

          {/* 애니매이션 주고 싶은걸 CSS컴포넌트로 감싸버린다. */}
          {/* 각각 스위치(true일때만 적용), 클래스 작명, 0.5초동안 실행 */}
          {/* ture / false값을 state로 저장해서 쓰자 */}
          <CSSTransition in={스위치} className="wow" timeout={2000}>
            <TabComponent 누른탭={누른탭} 스위치변경={스위치변경} />
          </CSSTransition>

        </div> 
      )
    }

    function TabComponent(props){

      useEffect( () => {
        console.log('TabComponent안의 useEffect');
        props.스위치변경(true);
      });

      if (props.누른탭 === 0) {
        return <박스><div>0번째 내용입니다.</div></박스> // styled component 먹인 사례 // 입장하자마자 0번째 내용으로만 뜨지?
      } else if (props.누른탭 === 1) {
         console.log('TabComponent안의 조건에 부합하는 값');
         return <박스><div>1번째 내용입니다.</div></박스>
      } else if (props.누른탭 === 2) {
        return <박스><div>2번째 내용입니다.</div></박스>
      }
    }

    function Info(props) {
      return (
        <>
        {/* {console.log(Number(props.id))} */}
          {/* {console.log(props.shoes[Number(props.id)])} 해당 신발 번호에 맞게 번호나오는 코드 */}
          <p> 재고 : {props.재고[0]} </p>
        </>
      )
    }

    export default Detail;

    ///////////////////////////////////////

    // import React from 'react';
    // import { useParams } from 'react-router-dom';

    // function Detail(props){

    //   let { id } = useParams();
    //   let 찾은상품 = props.shoes.find(function(상품){
    //     return 상품.id === id
    //   });

    //   return (
    //     <div className="container">
    //       <div className="row">
    //         <div className="col-md-6">
    //           <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" alt=""/>
    //         </div>
    //         <div className="col-md-6 mt-4">
    //           <h4 className="pt-5">{찾은상품.title}</h4>
    //           <p>{찾은상품.content}</p>
    //           <p>{찾은상품.price}원</p>
    //           <button className="btn btn-danger">주문하기</button> 
    //         </div>
    //       </div>
    //   </div>  
    //   )
    // };

    // export default Detail;

     

    질문1 :

    누른탭이 1일 때 콘솔창에 아래처럼 4번이 반복됩니다.

    TabComponent안의 조건에 부합하는 값

    TabComponent안의 useEffect'

    TabComponent안의 조건에 부합하는 값

    TabComponent안의 useEffect'

    TabComponent안의 조건에 부합하는 값

    TabComponent안의 useEffect'

    TabComponent안의 조건에 부합하는 값

    TabComponent안의 useEffect'

    이렇게 4번이 나오는데 왜 그런건지 궁금해서 질문올립니다.

     

    질문 2. 코드와 같이 

          <Nav className="mt-5" variant="tabs" defaultActiveKey="link-1"> 처음 detail페이지에 들어갔을 때 1번 탭이 눌리게 default를 지정했습니다. 헌데 밑의 내용으로는 '1번째 내용입니다'가 아닌

    0번째 내용입니다. 로 시작이 됩니다. 해결하고 싶은데 힌트좀 받을 수 있을까요?

    #10147

    강성구
    참가자

    질문 빠트린게 있어 하나 더 추가합니다

    선생님과 똑같은 코드를 따라쳤지만 CSSTransition이 적용 안돼고 있습니다. 

    #10148

    codingapple
    키 마스터

    3은 CSSTransition 컴포넌트로 싸맬 때 classNames 속성 오타인듯합니다 

    2는 defaultActive어쩌구 쓰려면 아마 부트스트랩 <Tab> 컴포넌트로 싸매야할걸요

    1 은 저도 모르겟읍니다 그 컴포넌트 재렌더링이 4번 일어나는군요 왜일까요 

    #10157

    강성구
    참가자

      {/* 부트스트랩 Tab만들기 복붙 */}
          <Nav className=”mt-5″ variant=”tabs” defaultActiveKey=”link-1″>{/* mt : 부트스트랩이 기본제공하는class margin-top-5 */}
            <Nav.Item>
              <Nav.Link eventKey=”link-0″ onClick={ () => { 누른탭변경(0), 스위치변경(true) }}>Active</Nav.Link>
            </Nav.Item>
            <Nav.Item>
              <Nav.Link eventKey=”link-1″ onClick={ () => { 누른탭변경(1), 스위치변경(true) }}>Option 1</Nav.Link>
            </Nav.Item>
            <Nav.Item>
              <Nav.Link eventKey=”link-2″ onClick={ () => { 누른탭변경(2), 스위치변경(true) }}>Option 2</Nav.Link>
            </Nav.Item>
          </Nav>

     

    선생님께서 작성하신 코드에서 스위치변경부분만 모두 true로 바꾼 코드입니다.

    맨처음 스위치 state를  false로 만들었고 버튼을 눌렀을 경우 true로 바꿔주라는 의미로 해석이 됩니다.

    그럼 해당 탭의 in={true}가 되며 정상적으로 CSSTransition이 적용되야 할것같은데 안되네요.

    이유를 알수 있을까요? 다른 탭들은 버튼을 누르지도 않았으니 다른것들은 그대로 false라서 모두가 true라는  충돌은 안 일어날거 같다 정도까지만 생각이 뻗쳤습니다.

    #10169

    codingapple
    키 마스터

    그것은 실험해봐야겠지만 아마 1. state변경함수는 차례로 동작하지 않고 async하게 동작해서

    2. 탭컴포넌트가 재랜더링되지 않아서 둘 중 하나의 이유일 것 같습니다 

5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 답변은 로그인 후 가능합니다.

About

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

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

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