45일차(1)/React(7) : React 실습예제 / CSS import해서 적용하기
App04_ex2.js (최종)
- 체크하면 아래 선택한 목록이 추가되도록 하기!
//App04_ex2.js
import { Component } from "react";
class App extends Component{
state={
selectedList:[]
}
//선택한 메뉴를 출력할 데이터를 담을 배열 (처음엔 선택한게 없어서 비어 있다)
selected=[];
render(){
let menu=[
{id:1, name:"김밥"},
{id:2, name:"라면"},
{id:3, name:"떡볶이"},
{id:4, name:"만두"},
{id:5, name:"우동"}
];
//data 를 이용해서 UI를 만들어내기 (만들어낸 UI는 배열에 저장된 상태로 리턴된다)
const newArray=menu.map((item)=>{
//item 은 {id:x, name:x} 형태의 object 이다.
return <label key={item.id}><input type="checkbox" onChange={(e)=>{
//체크 박스를 체크하거나 해제하면 호출되는 함수
//만일 체크 했다면
if(e.target.checked){
//필드에 선언된 selected 배열에 item 추가
this.selected.push(item);
}else{//체크를 해제 했다면
//삭제할 item 이 몇번째 index 에 있는지 찾아서
const index=this.selected.indexOf(item);
//필드에 선언된 selected 배열에서 해당 인덱스 삭제
this.selected.splice(index, 1);
}
//state 를 변화 시켜서 UI 가 업데이트 되게 한다.
this.setState({
selectedList:this.selected.map( item => <li key={item.id}>{item.name}</li>)
});
}}/> {item.name} </label>;
});
return(
<div className="container">
<h3>먹고싶은 분식 메뉴를 체크하세요.</h3>
{newArray}
<h3>선택된 메뉴 목록입니다.</h3>
<ul>
{this.state.selectedList}
</ul>
</div>
)
}
}
export default App;
- 이 예제에서는 새로운 배열을 얻어낼 필요가 없어서, filter를 사용하지 않는다.
- indexOf() 를 사용해서 개별 값의 인덱스를 얻어내서 인덱스를 사용해서 추가하고 삭제한다.
- selected=[]; 배열은 state로 관리할 필요가 없어서 selected 라는 필드로 만들었다.
아래에서 this.selected로 참조한다.
- jsx 객체가 들어있는 UI
- {} 안에 넣어주는 것만으로도 화면에 나타난다.
- { } 안에 배열을 참조하는 것만으로도 배열이 알아서 출력된다.
- onChange: 체크박스에 체크/해제하면 이벤트가 발생하도록 이벤트 걸어두기
[ 순수 javascript ]
1) <input type="checkbox" onchange="changed()">
function changed(){}
- change 이벤트가 일어나면 아래 함수가 호출됨!
2) document.querySelector().addEventListener("change",function(){ });
- 문서 객체의 참조값을 얻어와서 이벤트리스너로 호출
[ React ]
<input type="checkbox" onChange={()=>{}} />
<input type="checkbox" onChange={this.handleChange } />
handleChange= ()=>{ }
- change 이벤트가 일어나면 onChange={ } 안의 함수가 호출된다!
- 이미 만들어진 함수를 호출하는 것도 가능
- onFocus onBlur onSubmit onMouseDown 등등..
특정 요소에 어떤 이벤트가 발생하면 호출하도록 이벤트를 걸어놓을 수 있다.
- 함수가 길어서 헷갈리지만 함수가 빠져 있으면 이런 모양이다.
const newArray=menu.map((item)=>{
return <label key={item.id}><input type="checkbox" onChange={(e)=>{
//체크 박스를 체크하거나 해제하면 호출되는 함수
if(e.target.checked){
this.selected.push(item);
}else{
const index=this.selected.indexOf(item);
this.selected.splice(index, 1);
}
this.setState({
selectedList:this.selected.map( item => <li key={item.id}>{item.name}</li>)
});
}}/> {item.name} </label>;
});
- map 함수로 UI 를 만들어서 배열에 넣기 전에, 이벤트리스너 함수를 등록
- 함수를 호출하면서 이벤트리스너를 즉석에서 등록한 것과 같다.
- map 함수는 5개가 만들어진다. 하나를 만들어서 공유하는 것이 아니라 5개 만들어짐 (return이 5번!)
- 이 함수가 만들어지는 시점마다 아이템은 각자 다를 것이다.
ex) 1)김밥 2)라면 3)떡볶이, ...
- 이 함수 안에서 item이라는것은 코딩 시점에는 무엇을 가리킬 것인지 알 수 없다.
- 이 item이 무엇인지는 이벤트가 일어났을 때 결정된다. 사용자가 클릭하면 그때 item이 되는 것!
- 이 함수가 5개 만들어져 있는데, 그 함수에서 각각 item은 자신의 고유한 것을 가리키고 있다.
- 함수가 실행되면 이벤트객체 e가 전달된다. 이 객체는 리액트가 넣어준다.
- 체크되었을 때 필드의 빈 배열에 push로 아이템을 넣어준다.
this.selected.push()
- this.selected : 변화가 일어날 주체를 이 배열로 지정하는 것
- push() : 배열에 값 추가하는 함수
- 현재 아이템의 인덱스 값이 무엇인지 알아내서 몇번째 인덱스에 있는지를 리턴해주기 (indexOf로 찾을 수 있다)
- 찾은 인덱스 값으로 splice(삭제) 해주기!
- e.target.checked 의 체크 상태에 따라서 if~else 문으로 분기하여 <li>를 생성/삭제 한다.
- map 함수를 사용해서 <li>가 여러개 들어있는 UI를 만들어준다.
- <li>가 여러개 들어있는 배열로 setState() 하는 것이다. (상태값 재설정)
- state의 상태가 바뀌면 아래 return의 UI에 자동 업데이트된다.
App05.js - CSS 적용
//App05.js
import { Component } from "react";
//css/custom.css로딩하기
import "./css/custom.css";
/*
[ 모듈화된 css를 사용하는 방법 ]
1.css 파일의 이름에 .module.를 추가한다
2.from과 함께 import 해서 사용한다.
*/
import styles from "./css/custom.module.css";
class App extends Component{
state={
obj:{
color:"blue",
border: "1px solid red",
backgroundColor:"yellow"
},
isYellow:false
}
render(){
const classes="box bg-yellow";
return(
<div className="container">
<h1>css 적용 예제</h1>
<button onClick={()=>{
this.setState({
obj:{
...this.state.obj,
backgroundColor:"greenyellow"
}
});
}}>배경색 바꾸기</button>
<p style={this.state.obj}>p1입니다.</p>
<div className="box bg-yellow">box</div>
{/*
jsx에서 { 중괄호 내부 }
중괄호 내부는 javascript에서 사용하는 데이터가 참조되어야 한다.
ex) number, string, object, array, function
number=>10,20
string=> "abcd", 'abcd', `abcd`
object=> { key:value }
array=> [value2,value2]
function=> ()=>{}
- 데이터를 즉석에서 만들면서 참조할수도 있고, 이미 만들어진 데이터를 참조할 수도 있다.
*/}
<div className={"box bg-pink"}>box2</div>
<div className={classes}>box3</div>
<div className={`box bg-pink`}>box4</div>
<div className={`box ${ true ? "bg-yellow" : "" }`}>box5</div>
<div className={`box ${ false ? "bg-yellow" : "" }`}>box6</div>
<div className={`box ${ true && "bg-yellow" }`}>box7</div>
<div className={`box ${ this.state.isYellow ? "bg-yellow" : "" }`} onClick={()=>{
this.setState({
isYellow:!this.state.isYellow
})
}}>box8</div>
<p className={styles["text-red"]}>p요소입니다.</p>
<p className={styles["text-bold"]}>p요소입니다.</p>
<p className={`${styles["text-red"]} ${styles["text-bold"]}`}>p요소입니다.</p>
</div>
)
}
handleCss = (ref) => {
this.pRef="green"
this.setState()
}
}
export default App;
const obj={
color:"blue",
backgroundColor:"yellow"
}
return(
<div>
<h1>css 적용 예제</h1>
<p style={obj}>p1입니다.</p>
</div>
)
- object를 이용해서 css를 적용하고 싶다면? p style={obj} 로 적용
- obj 의 값이 계속 바뀌어야 한다. → state 로 관리하기!
- 이렇게 state 에 넣어두고 this.state.obj 로 적용해도 css가 제대로 잘 적용된다
- 검사에서 확인해보면 inline css로 들어가 있다.
- 클릭했을 때 this를 새로운 obj으로 바꾸려면 onClick 함수 안에 setState가 들어가야 한다.
- css의 background-color가 js문법에서는 backgroundColor(카멜 케이스) 로 사용된다는 것을 기억하기!
- obj 라는 방에 들어가 있는 배경색을 blue로 하고 setState 하면?
→ 기존에 있는 값을 다 없애고 새 값으로 덮어쓴다.
배경색 이외의 서식도(테두리, 글자색) 전부 없애 버린다.
- 하지만 기존의 값은 남기면서 덮어쓰고 싶다면? → ... 을 사용한다.
- 두 개는 같은 것이다. 기존 배열 안에 있는 데이터를 쫙 펼쳐놓고 추가한다고 생각하면 된다.
- ... 은 object 에서도 사용 가능하다.
- 기존의 object가 ...mem 안에 펼쳐지고, 추가한 내용이 추가되는 것이다.
- mem3 와 같이 방의 이름은 같고 value 값이 다르면 내용을 추가하는 것이 아니라 덮어 쓴 결과가 나온다.
- 해당 object 안에 들어있는 것을 펼쳐놓고, 특정 키 값에 있는 내용을 override 하는 것
- obj 의 현재 state를 쫙 펼쳐놓고, 그 안에서 배경색만 바꾸는 것
- obj도 object 이기 때문에,
{ ...this.state.obj, backgroundColor:"green" } 은 { key1:val1, key2:val2 } 형태로 작성된 것이다.(주의!)
- object를 잘 작성하도록 연습!
- 배경색만 바뀌고 나머지 서식은 그대로 유지됨!
src에 css폴더만들기 - custom.css 생성
/* css/custom.css */
.box{
width: 100px;
height: 100px;
border: 1px solid red;
}
.bg-yellow{
background-color: yellow;
}
.bg-pink{
background-color: pink;
}
import "./css/custom.css";
- import만 해도 외부 파일이 불러와져서 알아서 적용됨
- 이 경우 inline으로 적용된 것은 아니다. 검사에서 확인해보면 <style>이 따로 있다.
- className을 javascript {} 를 활용해서 전달할 수도 있다.
- {} 안에 문자열을 직접 작성해도 되고, 이미 만들어진 문자열을 참고해도 된다.
백틱 `` 을 사용해서 문자를 넣어도 된다.
ex) box1 : 문자열을 직접 작성한 것
box2 : 이미 만들어진 데이터를 문자열로 전달한 것
box3 : 문자열을 변수에 담아서 그 변수를 참조한 것
- 지금은 고정된 무언가가 들어가 있지만 저 클래스를 동적으로 움직이려면?
→ add class와 remove class를 react에서는 어떻게 하는지?
- 적용할 요소를 지정해서 xxx.add.class 해도 되지만, { } 를 사용해볼 수 있다.
- 3항연산자, && 으로 className 입력하기
- `` (백틱) 안에 javascript 를 넣으려면 ${ } 안에 넣어주면 된다.
- 위의 true/false 자리에 상태값(state)를 넣으면 동적으로 변화시킬 수도 있다!
- div 클릭시에 T/F 를 변환시킬 수 있는 함수를 넣어주기
this.setState({ isYellow : ! this.state.isYellow });
- T→F F→T 로 바꿀 수 있는 함수. 현재 state 값을 읽어내서 반전시키면 된다!
- box8 은 클릭시 색깔이 바뀌는 동적인 class를 가진 div가 된다.
- jsx에서 { } 는 뭔가를 참조하는 데 쓰는 javascript 영역인 것을 기억하기!
'국비교육(22-23)' 카테고리의 다른 글
46일차(1)/React(9) : 함수형 컴포넌트 작성 / ajax 요청으로 DB 데이터 출력 (0) | 2022.12.12 |
---|---|
45일차(2)/React(8) : 모듈화된 CSS 적용하기 / form 요소 활용 (0) | 2022.12.11 |
44일차(2)/React(6) : jsx 객체 활용, setState 함수 실습 (0) | 2022.12.08 |
44일차(1)/React(5) : React 저장소 clone하기 / React 코드 리뷰 (0) | 2022.12.08 |
43일차(3)/React(4) : filter 함수 / 자식 component 활용 예제 (1) | 2022.12.08 |