07) 아니요 저는 무리해서 공부해야 합니다

이희주·2022년 5월 17일
0
post-thumbnail

React

  1. state()의 동작 원리
  2. 게시글 목록 보기

어제 자유게시판 코드리뷰
index.js 안에 컨테이너가 있고 컨테이너 안에 프리젠터가 있는 구조

container, presenter가 index의 자식이 되고
presenter가 다시 container의 자식 요소가 된다

styles가 다시 presenter의 자식 요소가 되고
presenter안에서는 styles들이 사용된다.
(그래서 presenter에서도 emotion으로 props를 넘겨줄 수 있다.
부모에게 받은 props를 다시 자식에게 넘겨주고 하는걸 props drilling이라고 하는데 drilling이 많은 코드는 별로 좋지 않은 코드 !)

query부분은 부모자식 관계라고 보기는 어려움 !

부모,자식 관계들로 연결된 컴포넌트들을 확인 가능

container는 javascript 부분, presenter는 jsx(html)부분을 가지고 있다.
이렇게 두개로 파일을 나누긴 했는데 서로 기능이 연결된 것은 아니니까
props로 기능을 연결해준다key와 value의 형태로 props를 사용하여 함수와 기능들을 넘겨준 것 확인 가능

presenter가 styles의 부모 요소이기 때문에
presenter에서도 styles에 props를 줄 수 있다. 이렇게 하면 aaa가 실행될 때 label에 적용이 되는데,
이걸 props로 받을 함수가 없기 때문에
이렇게 함수를 만들어줘서 적용 가능

index.js에 container가 import 돼서 사용되고 있지만
다른 index에도 import 가능하다 !

그런데

router.query.boardId 는 [boardId]와 연결되어 있기 때문에

다른곳으로 import될 수 있지만 어떤곳에서 import가 되냐에 따라 router.query가 작동을 할 수도 있고 안 할 수도 있다

그래서 component안에서 router.query를 사용하게 될 경우 최종적으로 어떤 페이지에서 사용될지를 잘 생각해야 함(내가 생각한대로 작동 안 할 수도 있음)

setState 실습

input창 작성자,제목,내용 세개 모두 입력됐을때 버튼 색상을 노란색으로 변경해주고, 내용이 지워지면 다시 원래 색으로 돌려주기

1.index만들어준 뒤 지난시간에 했던 BoardWrite 페이지들과 연결해주기

2.emotion에 버튼 색을 지정 해준 뒤 presenter에 props 연결해주기

isActive가 boolean값으로 들거가기 때문에 props로 isActive가 true라면 yellow로, 아니라면 기본값으로 설정해주기isActive가 true인 상태이기 때문에 === true를 안 써도 됨

  1. container에 state를 만들어준 뒤 초기값을 false로 줌event.target.value

  2. isActive가 props를 타고 가서 연결될 수 있도록 연결해주기

  3. isActive를 props로 presenter에 보내준 뒤 presenter의 isActive를 styles로 보내준다

7.이 상태에서 true, false 값을 바꿔서 색을 바꿔주기 위해 setState를 사용

8.setState를 사용하여 작성자, 제목, 내용이 모두 입력되면 버튼색을 노란색으로 바꿔주기! 내용이 지워지면 다시 원래 색으로 돌아간다!

그런데 이렇게 하면 contents를 마지막으로 입력했을 때만 조건문이 작동하기 때문에 같은 내용은 writer, title에도 입력해줌 (이렇게 해야 어떤걸 마지막으로 입력해도 색이 바뀜)
그런데,,

1글자를 입력하면 색이 바뀌지 않고 2글자부터 색이 바뀐다??? 이유는?

setState의 원리를 알아야 한다

setWriter에 c를 입력하면 event.target.value에 c가 들어오고
writer가 c가 되어야 하는데 그런데 이때의 writer는 공백이다!
setState에 값을 넣는다고 바로 그자리에서 writer가 변하는게 아니라 함수가 종료되었을때 writer가 c 로 바뀌게 되는것
(setWriter를 마주치게 된다고 바로 바뀌는게 아니라 임시 저장공간에 writer를 c 로 바꿔줘 라고 해뒀다가 함수가 다 끝나게 되면 임시 저장공간에 있던 내용이 반영돼서 writer가 c로 바뀌게 되는것)

state가 변경되면 임시저장공간에 내용을 저장해두고 함수가 다 끝나게 되면 리렌더링으로 컴포턴트가 다시 만들어지게 되는것

한글자만 입력해도 적용되게 해주려면

if문의 writer, title, contents의 각 값을 event.target.value로 바꿔줌

map

["철수","영희","훈이"].map((i) => {return i + "어린이"})
(3) ['철수어린이', '영희어린이', '훈이어린이']

map과 html의 연결
철수,영희,훈이가 있고 그 배열에 map이 들어가게 되면

<div>{el}</div> 

부분에서 el이 각각 자리를 찾아 들어감(철수,영희,훈이)
그래서 div 부분에 철수, 영희, 훈이가 들어옴

출력 결과

map 실습

배열이 html에서 나타날 수 있다 (JSX에서만)

map을 이용해서 배열들을 div로 감싸주기

값이 변하지 않는 것들은 함수 밖으로 빼서 효율성을 높여준다 (리렌더링 되지 않도록) 보통 이런것들은 카멜케이스 말고 대문자_대문자 로 많이 사용됨

map을 이용해서 배열의 number, title을 div로 감싸주기

실행결과

playground에서 게시글 목록보기 배열 가져오기

배열 안에 객체가 10개씩 들어가있는것을 확인 가능

FRUITS와 동일한 형태를 가지고 있따

fetchboard로 playground에서 데이터를 가지고와서 화면에 뿌려주기

import { useQuery, gql } from '@apollo/client'
import styled from '@emotion/styled'

const FETCH_BOARDS = gql`
    query fetchBoards{
        fetchBoards{
            number
            writer
            title
            contents
        }
    }
`

const MyRow = styled.div`
    display: flex;
`

const MyColumn = styled.div`
    width: 25%;
`

export default function MapBoardPage(){
    const { data } = useQuery(FETCH_BOARDS)

    return (
        <div>
            {data?.fetchBoards.map((el) => (
                <MyRow key={el.number}>
                    <MyColumn><input type="checkbox" /></MyColumn>
                    <MyColumn>{el.number}</MyColumn>
                    <MyColumn>{el.writer}</MyColumn>
                    <MyColumn>{el.title}</MyColumn>
                </MyRow>
            ))}
        </div>
    )

}

fetchboard에서 받아온 배열(속 객체 10개)를 map으로 뿌리기
게시물 목록이 10개니까 MyRow가 10개고
input checkbox, number, writer, title도 각 10개씩 있다.

실행결과

=> playground fetchboard에서 같은 내용 확인 가능

(fetchboard에서 가지고왔던것과 같은데, map을 통해서 화면에 보여주는것의 차이)

map으로 가지고 온 배열을 삭제하기

import { useQuery, gql, useMutation } from '@apollo/client'
import styled from '@emotion/styled'
import { Fragment } from 'react'

const FETCH_BOARDS = gql`
    query fetchBoards{
        fetchBoards{
            number
            writer
            title
            contents
        }
    }
`

const DELETE_BOARD = gql`
    mutation deleteBoard($number: Int){
        deleteBoard(number: $number){
            message
        }
    }
`

const Row = styled.div`
    display: flex;
`

const Column = styled.div`
    width: 20%;
`

export default function MapBoardPage(){
    const [deleteBoard] = useMutation(DELETE_BOARD)
    const { data } = useQuery(FETCH_BOARDS)

    //onClickDelete 함수가 실행될 때 삭제가 되는 것!
    const onClickDelete = (event) => {
        deleteBoard({
            variables: { number: Number(event.target.id) },
            //삭제하기 위해 클릭한 게시물의 id
            //html에서 가지고 온 것이기 때문에 string이어서 Number로 바꿔줌

            //어떤 게시글을 삭제할건지 적어줘야 함
            //17번 글이면 Number(17)

            refetchQueries: [{ query: FETCH_BOARDS }]
            //삭제 버튼을 클릭하면 DB에서는 지워지는데 새로고침을 해야 화면에서도 지워짐
            //DB에서 지워지면 화면에서도 지워지게 리패치 하기 위해서 (엑셀 DB에 저장된 삭제되었다는 것을 꺼내오기)
            //삭제되면 아까쓰던거 말고 새로운 패치보드로 리패치 해줘! 하고 요청하는것 (여러개의 API도 가능 {},{},{})
        })
    }

    return (
        <div>
            {data?.fetchBoards.map((el) => (
                    // <Fragment key={el.number}>
                    // <Row key={el.number}>

                    //패치보드를 통해 배열속 게시물 10개를 가지고 온 뒤 삭제버튼을 추가함
                    <Row>
                        <Column><input type="checkbox" /></Column>
                        <Column>{el.number}</Column>
                        <Column>{el.writer}</Column>
                        <Column>{el.title}</Column>
                        <Column>
                            <button id={el.number} onClick={onClickDelete}>삭제</button>
                            {/* 삭제버튼을 누르면 해당 게시물이 삭제되게 하기 위해 버튼에 id로 el의 number값을 줌 */}
                        </Column>
                    </Row>
                ))}
        </div>
    )

}

1.패치보드를 통해 배열 속 게시물 10개를 가지고 온 뒤 삭제버튼을 추가함

2.삭제버튼을 누르면 해당 게시물이 삭제되게 하기 위해서 버튼에 id로 el의 number값을 줌

3.variables: { number: Number(event.target.id) }, 로 삭제버튼을 클릭하면 해당 게시물이 삭제될 수 있도록 함

4.fefetchQueries: [{ query: FETCH_BOARDS }] 로 리패치 요청
삭제 버튼을 클릭하면 DB에서는 지워지는데 새로고침을 해야 화면에서도 지워짐
DB에서 지워지면 화면에서도 지워지게 리패치 하기 위해서 (엑셀 DB에 저장된 삭제되었다는 것을 꺼내오기) 삭제되면 아까쓰던거 말고 새로운 패치보드로 리패치 해줘! 하고 요청해줌 (여러개의 API도 가능 {},{},{})

  1. </Row key={el.number}> 경고메세지가 뜨거나 게시물은 삭제됐는데 체크박스는 그대로인 경우를 방지하기 위해 10번 실행될때 key값이 게시물별로 각각의 다른걸로 들어가야하니까 id, number로 써줌

map에는
["철수","영희","훈이"].map((el, index) => el + "어린이" + index)
실행결과 ['철수어린이0', '영희어린이1', '훈이어린이2']
이렇게 고유한 인덱스 번호가 있기 때문에

key에 el.number 대신 index를 주면 문제가 없는 것 처럼 보이지만 index를 key로 주고 해당 게시물을 삭제하면, 밑에 있는 게시물이 해당 index로 들어오기 때문에 사용하면 안됨 (인덱스 1인 영희어린이를 삭제하면 훈이어린이가 인덱스 1이 됨)

<Fragement key={el.number}></Fragement> 와 
<></>는 같지만 Fragement를 기입해주면 안에 key 넣는것이 가능해짐!

Algorithm class


TIL

1.오류 관련 구글링 팁 최대한 작은 단위로 끊어서 검색하기

2.playground 가지고 올때 적는 부분이 헷갈린다 ㅠ ㅠ

playground 에서 데이터 받아올 때 $속 값이랑 id 잘 맞춰주기

variables : productId 위에꺼랑 맞춰주기

패치보드도 마찬가지로 $number 랑 맞춰주기

  1. freeboard 게시판 디자인 나한테 맞게 바꿔주기
profile
어제보다 오늘 발전하는 프론트엔드 개발자

0개의 댓글