리액트에서 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]
}
전환 애니메이션
- css에 애니메이션 동작 전 스타일 (className)
- css에 애니메이션 동작 후 스타일 (className)
- transition 속성 추가
/* 애니메이션 */
.start {
opacity: 0;
}
.end {
opacity: 1;
transition: opacity 1s;
}
- 원하는 태그에 속성 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가 들어간다.
⇒ 이럴 때 리턴 사용하는 것
'React' 카테고리의 다른 글
[React] 로컬 스토리지 (0) | 2024.03.22 |
---|---|
[React] Context Api와 redux (0) | 2024.03.22 |
[React] 리액트 부트스트랩 적용 (0) | 2024.03.21 |
[React] 간단한 맛집 추천 블로그 - 2 (0) | 2024.03.21 |
[React] 간단한 맛집 추천 블로그 - 1 (0) | 2024.03.21 |