React

[React] axios

sejin2 2024. 3. 22. 09:46

리액트에서 AJAX 사용하기 위해 설치를 해준다.

더보기

npm i axios

<Button variant="secondary" onClick={()=>{
  /* 
  axios.Method('서버url')
       .then((변수)=>{})  -> 성공했을 때
       .catch(()=>{})     -> 실패했을 때
  */
  axios.get('https://raw.githubusercontent.com/professorjiwon/data/main/data2.json') -> 서버의 주소
       .then((result)=>{
        console.log(result.data);
        let copy = [...clothes, ...result.data]
        setClothes(copy)
       })
       .catch(()=>{console.log('실패');})


  /*
  - 서버로 보낼때
  axios.post('서버 url', 보낼 데이터)
       .then((변수) =>{}) -> 성공했을 때
       .catch(() => {})   -> 실패했을 때

  axios.post('https://raw.githubusercontent.com', {name:'kim', age:20, tel:'010-1111-2222'})
       .then((변수)=>{})   -> 성공했을 때
       .catch(() =>{})     -> 실패했을 때
  
  - 여러 서버에 동시 요청
  Promise.all([axios.get('서버1url'), axios.get('서버2url')])
       .then((변수)=>{})  -> 성공했을 때
       .catch(() =>{})    -> 실패했을 때
  */ 

}}>서버에서 데이터 가져오기</Button>

⇒ 버튼 컴포넌트 : 클릭 이벤트가 발생하면 axios를 사용하여 지정된 URL에서 데이터를 가져온다.
axios는 자바스크립트에서 널리 사용되는 HTTP 클라이언트 라이브러리로, 웹 서버로부터 데이터를 비동기로 가지고 온다. 실제로 클릭 이벤트가 발생하면 axios.get() 메서드가 호출되며, 이 메서드는 매개변수로 전달된 URL에서 GET 요청을 보낸다.여기서 URL은 'https://raw.githubusercontent.com/professorjiwon/data/main/data2.json' 으로, 이 요청은 JSON 형식의 데이터를 가져온다. 요청이 성공하면 then() 메서드가 호출되어 결과를 처리한다.
이 경우, 결과는 result 매개변수로 전달되며, console.log()를 사용하여 결과를 콘솔에 출력하고, 가져온 데이터를 현재 옷(clothes) 배열에 추가한다. 그런 다음, setClothes() 함수를 사용하여 업데이트 된 배열을 상태로 설정한다.
요청이 실패하면 catch() 메서드가 호출되어 '실패'라는 메시지가 콘솔에 출력된다.

⇒ 클릭할 때마다 주소가 https://raw.githubusercontent.com/professorjiwon/data/main/data2.json
3 → 4 로 바뀌어야 하는데, 더 이상의 데이터가 없을 때 데이터가 없다고 alert창으로 알려주어야 한다.
버튼을 누를 때마다 버튼을 누른 count수를 세어 바꿔준다.

let [btnCount, setBtnCount] = useState(2);

초기 값 : 2

axios.get(`https://raw.githubusercontent.com/professorjiwon/data/main/data${btnCount}.json`)->서버의 주소
 .then((result)=>{
  console.log(result.data);
  let copy = [...clothes, ...result.data]
  setClothes(copy)
  setBtnCount(btnCount+1)
 })
  .catch(()=>{
  console.log('실패');
  alert('더 이상 상품이 없습니다.')
})

만약 값이 없으면,

상품 상세페이지 → 탭 만들기

import { Container, Row, Col, Button, Nav} from 'react-bootstrap';

<Nav variant="tabs" defaultActiveKey="link-0">
  <Nav.Item>
    <Nav.Link eventKey="link-0">탭 1</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="link-1">탭 2</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="link-2">탭 3</Nav.Link>
  </Nav.Item>
</Nav>
let [tab, setTab] = useState(0);


return(
  <>
    <Container>
      <Row>
        <Col md={6}>
          <img src={`${process.env.PUBLIC_URL}/img/clothes${findId.id+1}.png`} width="300px"/>
        </Col>
        <Col md={6}>
          <h4>{findId.title}</h4>
          <p>{findId.content}</p>
          <p>{findId.price}</p>
          <Button variant="secondary">주문하기</Button>
        </Col>
      </Row>
    </Container>


      <Nav variant="tabs" defaultActiveKey="link-0">
        <Nav.Item>
          <Nav.Link eventKey="link-0" onClick={()=> {setTab(0)}}>탭 0</Nav.Link>
        </Nav.Item>
        <Nav.Item>
          <Nav.Link eventKey="link-1" onClick={()=> {setTab(1)}}>탭 1</Nav.Link>
        </Nav.Item>
        <Nav.Item>
          <Nav.Link eventKey="link-2" onClick={()=> {setTab(2)}}>탭 2</Nav.Link>
        </Nav.Item>
    </Nav>


    {
      tab == 0? <div>내용0</div> : tab == 1? <div>내용1</div> : tab == 2? <div>내용2</div> : null
    } 
  </>
)

삼항연산자

if 문 ( return 안에서 할 수 없음 ) ⇒ 컴포넌트로

function TabContent() {
  if (tab == 0) {
      return <div>내용0</div>
  }  else if(tab == 1) {
      return <div>내용1</div>
  } else {
      return <div>내용2</div>
  }
}
<Nav variant="tabs" defaultActiveKey="link-0">
  <Nav.Item>
    <Nav.Link eventKey="link-0" onClick={()=> {setTab(0)}}>탭 0</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="link-1" onClick={()=> {setTab(1)}}>탭 1</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="link-2" onClick={()=> {setTab(2)}}>탭 2</Nav.Link>
  </Nav.Item>
</Nav> 

<TabContent />

탭이 없다는 오류가 나온다. → props로 tab을 넘겨준다.

let [tab, setTab] = useState(0);

<TabContent tab={tab} />

function TabContent(props) {
  if (props.tab == 0) {
      return <div>내용0</div>
  }  else if(props.tab == 1) {
      return <div>내용1</div>
  } else {
      return <div>내용2</div>
  }
}

props가 싫으면 매개변수를 받을 때 변수를 직접 입력해 주면 된다.

function TabContent({tab}) {
  console.log(tab);

  if (tab == 0) {
      return <div>내용0</div>
  }  else if(tab == 1) {
      return <div>내용1</div>
  } else {
      return <div>내용2</div>
  }
}

파라미터가 여러 개일 때,

배열

function TabContent({tab}) { 
    let a = [<div>내용0</div>, <div>내용1</div>, <div>내용2</div>]
    return a[tab] 
  }

전환 애니메이션

  1. css에 애니메이션 동작 전 스타일 (className)
  2. css에 애니메이션 동작 후 스타일 (className)
  3. transition 속성 추가
/* 애니메이션 */
.start {
  opacity: 0;
}

.end {
  opacity: 1;
  transition: opacity 1s;
}
  1. 원하는 태그에 속성 className 넣었다 뺐다 (애니메이션 효과)
    1 - Detail_03.js에 css파일 import해주기
import './../App.css';

      2 - css 적용하기

function TabContent({tab}) { 
    
    return ( 
      <div className='start end'>
        { [<div>내용0</div>, <div>내용1</div>, <div>내용2</div>] [tab] }
      </div>
    )
     
  }

⇒ start end가 같이 적용되어 애니메이션 효과가 보이지 않는다.
처음 탭을 누르면 end가 빠지고 start만 적용되어 글씨가 안보이다가, 다시 탭을 누르면 end가 적용되어 보여야 한다.
===> useEffect사용

function TabContent({tab}) { 
    let [fade, setFade] = useState('');
    
    useEffect(()=>{
      setFade('end')
    }, [tab])
    
    return ( 
      <div className={`start ${fade}`}>
        { [<div>내용0</div>, <div>내용1</div>, <div>내용2</div>] [tab] }
      </div>
    )
     
  }

-> 이렇게 까지만 하면 처음 로딩 될 때만 애니메이션 효과가 나타난다.

function TabContent({tab}) { 
    let [fade, setFade] = useState('');
    
    useEffect(()=>{
      setTimeout(()=>{setFade('end')}, 300) 
      return() => {
        setFade('')
      }
    }, [tab])
    
    return ( 
      <div className={`start ${fade}`}>
        { [<div>내용0</div>, <div>내용1</div>, <div>내용2</div>] [tab] }
      </div>
    )
     
  }

렌더링하고 useEffect 실행하는데, 그중에서도 return( )안의 내용부터 시작한다.
‘ ‘ 아무 내용이 없는 상태에서 end가 추가되면서 애니메이션이 된다.
다른 탭으로 변경이 되었을 때에도 다시 return으로 들어가서 ‘ ‘ 상태에서 end가 들어간다.
⇒ 이럴 때 리턴 사용하는 것