11/08 map사용

김하은·2022년 11월 8일
0

오늘은 먼저 state의 이벤트(클릭등..)실행시의 원리를 알아보았다.
setState()여기의 소괄호 안의값과 초기값이 다르면 변경하는 원리로 작동한다.
바뀐값은 다시 state로 들어가고 바뀐다음 화면에 다시 그려주는데, (js의 코드 다시 실행)즉, use로 시작되는 훅을 제외, 다시그려주는 것이다.
따라서 완전히 바뀐값이되어 딱 하고 나오는 것이 아니라, state가 바뀌어(즉 초기값이 변경됨) 다시 그려주는 리렌더링의 과정을 거친다.
함수도, 변수도 이 과정에서 다시 그려준다.

리렌더링 비효율성 개선

setState가 여러개 한 함수에 있으면 임시 저장공간에 저강해놓는다. 그런식으로 차곡차곡 해당 함수가 끝날때까지 쌓이고, 함수끝나기전까지는 state가 바뀌지 않는다.
거기다가 맨 마지막 값만 받아 리렌더링 한번만되도 기존의 위에서 setState를 한것들(이전에 한것들)은 무시된다.

오늘 실습은 input박스가 다 채워졌을 경우, 버튼의 색이 바뀌는 것을 해보았다.
같은 함수 내에있는 if문의 경우에도 함수가끝나야 실행되므로 글자 하나 입력시에는 함수가끝날때까지 내려가며 리렌더링 될 시간이 있기에 바로 state에 들어가 값이 바뀌지 않는 것이다.
따라서 두번째글자가 작성되어야 첫번째글자작성했을때의 리랜더링이 적용되어 그때서야 해당if문이 실행되는 것이다.
따라서 if문에 각각 자신의 자리에 event.taget.value를 넣어 리랜더링 되기전의 값과 비교하여 바로 적용될 수 있게 한다.

`const [mycolor,setColor] = useState(false)

==>
const onChangeWrite = () => {
setWriter(event.target.value)
if(event.target.value && title && contents){
setColor(true)
}
}`

if문의 비교는 함수가끝나기전에 하고, 값은 함수가 끝난 뒤 넣어주는 형태로 하면 적용이 바로 됨을 알 수 있다.

map의 사용

배열에만 사용한다는 map.
사실 저번에도 한것 같은데 왜 기억이 안나나 싶어서 더 집중해서 들었다.

["철수","짱구","유리","훈이","맹구].map((el)=>{
return el+"어린이"
}
}
==>"철수어린이","짱구어린이","유리어린이","훈이어린이","맹구어린이"

 map은 해당배열의 길이만큼 자동으로반복된다.
 

주의사항: return과 중괄호 사이에 아무것도 없다면(if문이나 for문등) return과 중괄호를 지우고, 소괄호로 바꿀 수 있다. 다만 return 앞에 if문 등이 있으면 절대 return과 중괄호를 생략해서는 안된다.
그리고 물론, el의 앞에도 아무것도 없다면 그부분의 소괄호도 생략이 가능하다.

el란?: 각각의 요소들이 map이 돌때마다 하나씩 들어간다.

Map과 html연결.

`//벡엔드에서 받아온 데이터라고 가정.(컴포넌트위에 만든 이유:컴포넌트 리렌더링되도 다시 안만들어짐
//(변하지 않는 값(상수)등.emotion,gql등을 function의 밖에서 즉, 컴포넌트 밖에서 만든이유임 )
const classmate = [
{ name: "철수", school: "떡잎유치원" },
{ name: "영희", school: "떡잎유치원" },
{ name: "훈이", school: "떡잎유치원" },
];

export default function MapFruitsPage() {
const aaa = [

<div>1 레드향</div>,
<div>2 샤인머스켓</div>,
<div>3 산청딸기</div>,

]; //가장 기본예제

// 실무형 예제(aaa와 같은 결과.데이터만 지금 다르게 넣은것)
const bbb = [
{ name: "철수", school: "떡잎유치원" },
{ name: "영희", school: "떡잎유치원" },
{ name: "훈이", school: "떡잎유치원" },
].map((el) => (

<div>
  {el.name} {el.school}
</div>

));

// 또는
//결과 같음.

const ccc = classmate.map((el) => (

<div>
  {el.name} {el.school}
</div>

));
return <>{bbb}</>;
}
`

{각요소. 객체 키 명}={el.key}

이렇게 태그 안에 쓰는 것도 가능하다. 따라서 배열의모든 요소들을 원하는대로뽑아 태그에 넣을 수 있다!

*폴더를 만들어 그 안의 index.js를 실행하는 방법과 그냥 파일을 만들어 그 파일이름으로 실행하는 방법이 있으나, 주로 폴더를 만들어 그 안에 파일을 넣는 방법을 사용한다.

배열에 객체가 들어가는경우
{return

{el.키명}
}
벡엔드에서 받아오는 데이터는 배열에 들어있는 객체형태이다.
따라서 반복되는 값들은 map을 사용해 뿌려주는 것이 훨씬 깔끔하다.

가로:row(행)
세로:column(열)

event.target ==>태그를 볼 수 있다
event.target.id ==> id가 지정된 태그의 id를 가져온다.

게시물 삭제하기:
네트워크탭을확인해보면 무사히 지워지긴했으나, 화면에는 새로고침해야 반영이된다.
삭제한 이후 지운것을 째고 다시 fetch해줄 필요가 있다.
삭제 variables의 뒤쪽에
, refetchQueries[]
이렇게 쓰고 배열안에는 {query:fetch이름}이런식으로 작성해 한번 더 리페치를 해준다.
그러면 삭제후 리페치되어 새로고침한것처럼 다시 삭제된것으로 그려주게된다.

이번에는 체크박스를 활용해보았다.
체크를 해서 그부분을 삭제버튼으로 지우는 것이었다.
그런데 체크박스부분만 남아있는 형태가 되었다.

map을 그릴시 리엑트에서 효율성을 위해 원본? 을 기억하고있기때문에 그렇다는 것이다. 전체행에 key라는 것을 주어 다 다른애들이라고 번호를 매겨야 이 문제가 해결된다.
key={el.겹치지않는 아이디나 넘버} 이렇게 주어 중괄호 안에는 요소중에서 가져오는 아이디나 넘버를 기준으로 적어주면 겹치지 않는 값을 넣어주는것이된다.
이렇게바꿔놓고 실행하면 그 줄을 체크박스까지 포함하여
통채로 삭제가 가능해진다.!!

map에서 el말고 또 하나가들어올 수 있는데, 바로 index이다.
인덱스 번호가 들어오게된다.

그럼 key로 인덱스 번호를 쓰면 겹치지 않는것이 아닌가?

물론 그렇게해도 지워는 진다. 다만 의도한대로 한줄 전체가 지워지는 것이 아니라, key를 적용하지 않았을때와 같은형태로 체크박스만 남기고 지워진다.

왜?
인덱스를 키로해서 해당부분을 지웠다 하더라도 아까 지우고나서 리페치하여 다시 지운것을 반영한것을 그려주어 삭제가 적용되게 하였는데, 리페치되면서 해당 인덱스가 다시 생기게되어 적용이 되지 않는것이다.

따라서

키로 사용할 수 있는 것은 중복되지 않고!!
인덱스값이 아닌!! 것이어야 한다.

또하나!
*빈 프래그먼트태그 <></>에는 속성을 적용하지 못한다. 속성을 적용하고자할 때에는 라고 채워져있는 태그를 사용하자.

알고리즘: reduce메서드.

배열의 각각의 요소들을 총 연산한 결과값을 return 한다.
el과 cu값으로 받아온다.
el은 요소, cu는 cu와 el의 합이다.

const sum = arr.reduce((el,cu)=>{},여기에 cu값을 넣어줄 수 있다.)

0개의 댓글