React Project 만들기
yarn global add create_react_app
yarn global add npx
npx create-react-app myapp
yarn add prop-types
package.json과 같은 경로에 .env 파일 만듬
.env 안에 NODE_PATH=src
port 설정도 .env 안에
yarn add react-router-dom
----react 구조-----
* index.js - render App.js
* App.js, GlobalStyle.js render Router.js,GlobalStyle.js THEN export App
* Router.js 감싸기
<Router>
<>
<Header />
<Switch>
<Route path="/" exact component={Home} />
<Route path="/tv" component={TV} />
<Route path="/search" component={Search} />
<Route path="/movie/:id" component={Detail} />
<Route path="/show/:id" component={Detail} />
<Redirect from="*" to="/" />
</Switch>
</>
</Router>
THEN export ()=>
*Routes { index>container>presenter }
대부분 Routes 안의 container에서 코딩이 이루어짐.
search input 을 header 처럼 사용하고 싶으면 routes 안에 search container를 만들고,
Router.js 부분에서 searchcontainer를 import 해준후, <Router> 안쪽에 감싸주면됨
----search input을 상단에 항상 표시하기---
export default () => (
<Router>
<>
<Header />
<YoutubeSearch />
<Switch>
<Route path="/" exact component={Home} />
<Route path="/tv" component={TV} />
<Route path="/search" component={Search} />
<Route path="/movie/:id" component={Detail} />
<Route path="/show/:id" component={Detail} />
<Redirect from="*" to="/" />
</Switch>
</>
</Router>
대부분의 로직 코딩은 container에서 하면 됨
----page 에서 아이템 지우기---
React는 state{} 객체안에 있는 변수들을 화면에 뿌려주는 방식임
즉, youtubeAPI를 통해서 검색되온 아이템들을 지우고 싶다면
container.js 에
handleOnClick = async () => {
try {
this.setState({
youTubeResult: null,
loading: false,
});
} catch (error) {
this.setState({ error: "click error." });
}
};
함수를 만들어주고
Presenter.js 쪽
<Container key={youtube.videoId} onClick={handleOnClick}>
...
</Container>
----아이템 클릭후 axios 요청하기----
presenter.js
<Link
to={{
pathname: "/ytcrawl",
state: {
youtubeData: youtube,
inputStr: searchTerm,
},
}}
replace
>
container.js
// 컴포넌트가 탑재되면 이 이벤트 발생
async componentDidUpdate(prevProps) {
try {
if (this.props.location.state !== prevProps.location.state) {
const { youtubeData } = this.props.location.state;
const { inputStr } = this.props.location.state;
const {
data: { crawledIdx },
} = await youtubeCrawlApi.crawl(youtubeData, inputStr);
console.log("## youtubeData:", youtubeData);
this.setState({ loading: false, result: crawledIdx });
}
/*
if (this.state.result !== crawledIdx) {
this.setState({ loading: false, result: crawledIdx });
}
*/
} catch (error) {
} finally {
}
replace 라는 키워드가 똑같은 url에 진입시 강제 refresh를 해준다
container 쪽엔 componentDidUpdate(prevProps) 라는 lifecycle 이벤트 method를
사용하여 axios 요청을 하는데, 이 안에서 setstate() 을 쓰면 무한 루프에 빠진다.
그래서 검증하는 코드가 필요한데,
Link 쪽에서 넘겨준 props 와 전에 있던 props가 다를때 작업을 수행하도록 해야한다 .
아니면 현재의 state 변수와 전단계의 state 변수를 비교해도 좋다.
}
-------클릭 이벤트 만들기-----
container.js
clickCrawledIdx = async () => {
console.log("## clicked");
this.setState((state) => ({
showVideo: true,
}));
};
render() {
//model에 있는 데이터를 뷰로 보내주는 패턴
const { result, error, loading, showVideo } = this.state;
return (
<YoutubeCrawlPresenter
result={result}
error={error}
loading={loading}
showVideo={showVideo}
clickCrawledIdx={this.clickCrawledIdx}
/>
);
}
임의의 함수를 만든다
함수를 presenter로 넘겨줄땐 this. 를 사용해서 넘겨준다
preesenter.js
<Container>
<ItemContainer>{showVideo ? <div>aa</div> : null}</ItemContainer>
<ItemContainer onClick={clickCrawledIdx}>
crawled idx: {result}
</ItemContainer>
</Container>
onClick 이라는 이벤트 리스너를 div tag에 걸어주고, onClick은 전달받은 함수를 실행시킨다.
jQuery에서 div 숨기기 기능 구현은 스위치 변수 하나를 전달 받고, 그 변수 값에 따라서 div 를 랜더링 할지,
null을 랜더링 할지를 결정하면 됨
redux 개념
https://helloinyong.tistory.com/109
https://velopert.com/3533
eoeedddsdsee
sdsdsr
ssddd
댓글
댓글 쓰기