1. usestates와 props
-일반적인 javascript 사용-
<! DOCTYPE html >
< html >
< body >
< span > total clicks : 0 </ span >
< button id = "siu" > click me </ button >
</ body >
< script >
let counter = 0 ;
const buttons = document . getElementById ( "siu" );
const span = document . querySelector ( "span" );
function clickable () {
console . log ( "clickkkk" );
counter = counter + 1 ;
span . innerText = `total clicks : ${ counter } ` ;
}
buttons . addEventListener ( "click" , clickable );
</ script >
</ html >
-react(useState)를 사용하여 간결화-
import React from 'react' ;
function App () {
const [ minutes , setMinutes ] = React . useState ( 0 );
const [ flipped , setFlipped ] = React . useState ( false );
const onChange = ( e ) => {
setMinutes ( e . target . value ); // 입력 값이 변경될 때 상태 업데이트
};
const reset = () => setMinutes ( 0 ); // minutes 상태를 0으로 리셋
const onFlip = () => {
reset (); // 상태를 0으로 리셋
setFlipped ( ! flipped ); // flipped 상태를 반전
};
return (
< div >
< h1 className = "h1" > Super Convert </ h1 >
< label htmlFor = "minutes" > Minutes </ label >
< input
value = { flipped ? minutes * 60 : minutes } // 상태에 따라 값 결정
id = "minutes"
placeholder = "Minutes"
type = "number"
onChange = { onChange } // 입력 값 변경 시 상태 업데이트
disabled = { flipped } // flipped가 true일 때 입력 필드를 비활성화(###disabled속성이 'true'일 때 비활성화 된다.###)
/>
< button onClick = { onFlip } > Flip </ button > { /* 버튼을 추가하여 flipped 상태를 토글 */ }
< div >
< label htmlFor = "hours" > Hours </ label > //React에서 DOM 속성 이름이 JavaScript의 예약어와 충돌
< input
value = { flipped ? minutes : Math . round ( minutes / 60 ) }
id = "hours"
placeholder = "Hours"
type = "number"
disabled = { ! flipped } // flipped가 false일 때 입력 필드를 비활성화
/>
</ div >
< button onClick = { reset } > Reset </ button > { /* 버튼에 텍스트 추가 */ }
< button onClick = { onFlip } > Flip </ button > { /* 버튼에 텍스트 추가 */ }
</ div >
);
}
export default App ;
-props를 사용안할 시-
import React from 'react' ;
function RedButton () {
return < button style = { { backgroundColor : 'red' , color : 'white' } } > Click Me </ button > ;
}
function GreenButton () {
return < button style = { { backgroundColor : 'green' , color : 'white' } } > Click Me </ button > ;
}
function App () {
return (
< div >
< RedButton />
< GreenButton />
</ div >
);
}
export default App ;
-props- 를 사용할 시
import React from 'react' ;
function Button ( props ) {
return (
< button style = { { backgroundColor : props . bgColor , color : 'white' } } >
{ props . text }
</ button >
);
}
function App () {
return (
< div >
< Button bgColor = "red" text = "Click Me" />
< Button bgColor = "green" text = "Submit" />
</ div >
);
}
export default App ;
<Btn text = {value} onClick = {changeValue} /> 에서 이 onclick은 단지 props에 저장되는것이다 즉 html에서 사용되려면 function Btn({text, onClick}) return ( ~~~~~~ onClick = {onClick}) 이런 식으로 사용해야 한다.(가로 안에onClick이 props이다.)
2. prototypes
import PropTypes from "prop-types" ;
import styles from "./Button.module.css" ;
function Button ({ text }) {
return < button className = { styles . title } > { text } </ button > ;
}
Button . propTypes = {
text : PropTypes . string . isRequired ,
};
export default Button ;
npm install prop-types를 사용해 propTypes가 string이 아닐시(문자열) 경고를 보내게 할 수 있는 등. 코드의 가독성 및 오류를 잡는데 중요하게 사용된다.
3.CSS 모듈
import Button from "./Button" ;
import styles from "./App.module.css" ;
function App () {
return (
< div >
< h1 className = { styles . title } > Welcome back!!! </ h1 >
< Button text = { "Continue" } />
</ div >
);
}
export default App ;
App.js
.title {
font-family : -apple-system, BlinkMacSystemFont, "Segoe UI" , Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans" , "Helvetica Neue" , sans-serif ;
font-size : 18px ;
}
App.module.css
위와 같이 css모듈을 사용해 CSS 파일의 클래스를 로컬화(scoped) 해준다.
===>(css파일에서 .title(변수2) 와 같이 만들고 import된 파일에서는 변수1(styles).title(변수2)와 같이 사용한다.
4.useEffect
-useEffect는 우리가 한 번만 실행 할 수 있도록 도와준다.
import Button from "./Button" ;
import styles from "./App.module.css" ;
import { useState , useEffect } from "react" ;
function App () {
const [ counter , setValue ] = useState ( 0 );
const onClick = () => setValue (( couter ) => counter + 1 );
console . log ( "kim hyun jun" );
useEffect (() => {
console . log ( "call once" );
},[]);
return (
< div >
< h1 > { counter } </ h1 >
< h1 > hello </ h1 >
< button onClick = { onClick } > click me </ button >
</ div >
);
}
export default App ;
useEffect(() => {
},[]);
를 사용해서 한번만 call once가 출력해주도록 해주었다.(당연히 return 값에 useState();를 적용해준것이 아니니 화면에는 찍히지 않고 콘솔창에서 call once가 뜨고 사라진다.
5. ...currentArray
import { useState } from "react" ;
function App () {
const [toDo , setToDo ] = useState ( "" );
const [toDos , setToDos ] = useState ([]);
const onChange = (event ) => setToDo ( event . target . value );
const onSubmit = (event ) => {
event . preventDefault ();
if (toDo === "" ) {
return ;
}
setToDos (( currentArray ) => [toDo , ... currentArray ]);
//todo의 값에 ...currentArray을 추가한다. 즉, currentArray에 값이 1,2,3이 들어오면 이 element를 돌려주기 때문에 [todo의 element,1,2,3]으로 들어간다.
//todo = '' 이렇게 쓰지 않는 이유는 직접적으로 state를 고치지 않기 때문이다. 즉,변화하는 settodo("");를 이용해 초기화 시켜준다.
setToDo ( "" );
};
return (
< div >
< h1 > My To Dos ( { toDos . length } ) </ h1 >
< form onSubmit = { onSubmit } >
< input
onChange = { onChange }
value = { toDo }
type = "text"
placeholder = "Write your to do..."
/>
< button > Add To Do </ button >
</ form >
</ div >
);
}
export default App ;
6.map
console . log ( toDos . map (( item , index ) => < li key = { index } > { item } </ li > ));
return (
< div >
< h1 > My To Dos ( { toDos . length } ) </ h1 >
< form onSubmit = { onSubmit } >
< input
onChange = { onChange }
value = { toDo }
type = "text"
placeholder = "Write your to do..."
/>
< button > Add To Do </ button >
</ form >
< hr />
< ul >
{ toDos . map (( item , index ) => (
< li key = { index } > { item } </ li >
)) }
</ ul >
</ div >
);
첫번째 argument는 value이고(각각의 todo를 의미).두번째 argument는 index이다.
7. fetch
const [loading , setLoading ] = useState ( true );
const [coins , setCoins ] = useState ([]);
useEffect (() => {
. then (( response ) => response . json ())
. then (( json ) => {
setCoins ( json );
setLoading ( false );
});
}, []);
fetch함수가 api를 호출하고 응답(response(호출))를 받으면 JSON 데이터를 받아온다.
받아온 데이터를 setCoins(json)을 통해 상태로 저장된다.
데이터가 불러진 후 로딩 상태를 'false'로 바꾸어준다.
8.async/await
const [loading , setLoading ] = useState ( true );
const [movies , setMovies ] = useState ([]);
const getMovies = async () => {
const response = await fetch (
);
const json = await. response.json();
setMovies ( json . data . movies );
setLoading ( false );
};
useEffect (() => {
getMovies ();
}, []);
를 더 간단히 만들어 아래와 같이 만든다.
const [loading , setLoading ] = useState ( true );
const [movies , setMovies ] = useState ([]);
const getMovies = async () => {
const json = await (
await fetch (
)
). json ();
setMovies ( json . data . movies );
setLoading ( false );
};
useEffect (() => {
getMovies ();
}, []);
9. route
import { BrowserRouter as Router , Routes , Route } from "react-router-dom" ;
import Detail from "./routes/Detail" ;
import Home from "./routes/Home" ;
function App () {
return (
< Router >
< Routes >
< Route path = "/hello" element = { < h1 > Hello </ h1 > } />
< Route path = "/movie" element = { < Detail /> } />
< Route path = "/" element = { < Home /> } />
</ Routes >
</ Router >
);
}
export default App ;
-switch문을 더이상 현재 버전에서 쓰지 않기 때문에 중간에 switch를 Routes로 바꾸어 주었고 경로를 Routh path로 이동하게 한 후 element값 즉, js파일을 불러온다.
useParams
react-router는 바로 이 변수의 값을 넘겨준다.
import { useEffect , useState } from "react" ;
import { useParams } from "react-router-dom" ;
function Detail () {
const { id } = useParams ();
const [ movie , setMovie ] = useState ( null ); // 영화 정보를 저장
const [ loading , setLoading ] = useState ( true ); // 로딩
const [ error , setError ] = useState ( null ); // 오류
const getMovie = async () => {
try {
if ( ! response . ok ) {
throw new Error ( "Network response was not ok" );
}
const data = await response . json ();
setMovie ( data . data . movie ); // 상태에 영화 정보를 저장
setLoading ( false ); // 로딩 상태 변경
} catch ( error ) {
setError ( error . message ); // 오류 상태 저장
setLoading ( false ); // 로딩 상태 변경
}
};
useEffect (() => {
getMovie ();
}, [ id ]);
if ( loading ) return < p > Loading... </ p > ; // 로딩
if ( error ) return < p > Error: { error } </ p > ; // 오류
if ( ! movie ) return < p > No movie data found </ p > ;
return (
< div >
< h1 > { movie . title } </ h1 >
< p > { movie . year } </ p >
< p > { movie . summary } </ p >
< img src = { movie . medium_cover_image } alt = { movie . title } />
< ul >
{ movie . genres . map (( genre ) => (
< li key = { genre } > { genre } </ li >
)) }
</ ul >
</ div >
);
}
export default Detail ;
detail.js
-영화정보를 저장,로딩,오류 페이지로 나누어 준 후 데이터를 가지고 온다면 setMovie를 통해 저장을 해 준 후, loading 상태를 false로 바꾸어준다,(에러 메시지가 뜰 때고 위와같은 상황을 반복해준다.)
-> 렌더링이 될 때나 id 값의 변화가 있을 때 getMovie();에서 영화에 대한 정보를 가지고 온다.
->가져온 데이터의 genre에 고유 키값을 주어서 렌더링 되거나 id값이 변화할 때 값을 식별하게 해준다.
------------------------------------------------------------------------------------------------------
switch문이 react전 버전이라 Route와 element로 바꾸는 것 이외에 어려운점은 없었다.