Notice
Recent Posts
Recent Comments
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

HYEWON JUNG의 개발일지

20231117-19 WIL 페이지 보수 , redux 본문

개발일지

20231117-19 WIL 페이지 보수 , redux

혜won 2023. 11. 20. 04:34

목표

  • redux
  • 렌더링 최적화하기

새로 알게 된것/ 오늘의 코드

redux로 변경하는데 개념이 이해가 가면서도 이해가 가지 않는 부분이 많았다. 엄청많은 오류를 보고나서야 해냈다. 

redux 모듈은 2개로 만들고   writeTo로 필터링할 것 하나, 데이터 하나 해서 만들었다. 

 

가장 먼저 한 것은 편지를 추가하는 기능 부터 손을 댔다. 아무래도 강의에서 배운 todolist 리팩토링과 비슷할 것 같아서,

module / fanletter.js

import { data } from 'shared/fakedata'

export const addLetter = (payload)=>{
    return {type: "ADD_LETTER", payload}
}

const initialState = {
    letters : data
}

const fanletter = (state = initialState, action)=>{
    // console.log("state=>",state)
    // console.log("letters=>",state.letters)
    switch(action.type){
        case "ADD_LETTER":
            return {
                ...state,
                letters:[...state.letters, action.payload]
            }
        default: 
            return state
    }
}

export default fanletter

 초기값으로 fakedata를 넣어주고  payload를 받아와서 전개구문 한 state에 letter의 value를 바꿔준다. 기존의 state.letters를 풀어서 payload로 가져온 값을 추가해주는 로직이다. 

 

form.jsx

  const addLetterHandler = function (event) {
    event.preventDefault()
    if (nickname === "" || content === "") {
      alert("닉네임과 내용은 필수입니다!")
    } else {

      dispatch(
        addLetter({
        "createdAt": `${years}-${month + 1}-${day} ${hours}:${minutes}`,
        "nickname": nickname,
        "avatar": defaultAvarta,
        "content": content,
        "writedTo": writedTo,
        "id": uuid(),
        "isEdit": false
        })
      )
      setContent("")
      setNickname("")

    }

  }

 

클릭이벤트에 setLetters 해주던 부분을 dispatch로 변경해서 작성해주었다. 

payload에는 새로운 편지를 만들 객체가 들어가고 reducer에서 새로운 배열을 뱉어낸다.

이런 식으로 기존 set로직을 dispatch로 바꿔주고  context를 useSelector로 변경해서 진행했다. 

 

오류가 났던 부분은 

처음 수정을 구현할 때 if문까지 몽땅 들고가서 했는데 왜인지 오류가 계속 났다. 

  const [isEdit, setIsEdit] = useState(false)
  const [editedLetter, setEditedLetter] = useState(foundLetter.content)

  const editTextHandler = (event) => { setEditedLetter(event.target.value) }

  const finishEditHandler = (id) => {
    const editcontent = fanletter.letters.map((item) => ({
      ...item, content: item.id === id ? editedLetter : item.content

    }))
    if (editedLetter === foundLetter.content) {
      alert("수정된 부분이 없습니다.")
    } else {
      dispatch(
        editLetter(editcontent)
      )
      setIsEdit(false)
    }

  }

 

이부분인데  모듈에서 인자로 payload와 data 이런식으로 두개를 받아오게 했는데 이게 계속 수정칸에 들어가는 것은 문제가 없는데 수정완료를 누르면 수정사항이 완전히 사라졌다. 제대로 데이터가 바뀌지 않는 것 같았다. 그러다 보니 context를 아직 사용하고 있는 것을 발견해서 바꿔주고 해야겠다. 생각해서 진행하는데 계속 content가 없다는 오류가 뜨는 것이다..

 

그래서 그냥 처음 상태로 돌려버리고 다시 진행을 했다. 

뭐가 문제였는지 알 수 없게 진행이 되버리고 말았다.. 흑 기록해둘걸.. 

 

아무튼 두번째 난관은  헤더의 분류버튼 이었다. context까지 진행했을 때 까지도 분류 버튼을 하드코딩으로 진행했는데 그걸 그대로 진행하면 dispatch가 4개나 생기기 때문에 코드를 수정해야했다. 

module/ filteredLetter.js

export const writeToSelect = (payload)=>{
    return {type : "FILTERED_LETTER", payload}
}

const initialState = {
    select : "아이돌 솔로가수 배우" 
}


const filteredLetter = (state = initialState, action)=>{
    switch(action.type){
        case "FILTERED_LETTER":
           
            return {
                ...state, 
                select: action.payload
            }

        default: 
            return state
    }
}

export default filteredLetter

모듈을 만들어주고  헤더에선 dispatch를 letters에선 useselector를 했다. 

letters.jsx

function Letters() {

  const navigate = useNavigate();
  const fanletter = useSelector((state)=>{
    return state.fanletter;
  })
  // console.log(fanletter)
  const writeToselect = useSelector((state)=>{
    return state.filteredLetter;
  })

  return (
    <div>
      {fanletter.letters 
        .filter((L) => {
          return writeToselect.select.includes(L.writedTo)
        })
        .map((letter) => {
          return (
          <LetterStyle key={letter.id} onClick={() => { navigate(`/detail/${letter.id}`) }}>
              <div>
                <LetterImg src={letter.avatar} alt=''></LetterImg>
              </div>
              <div>
                <p>{letter.nickname}</p>
                <TimeStyle>{letter.createdAt}</TimeStyle>
                {letter.content.length <= 45 ? <ContentStyle>{letter.content}</ContentStyle> : <ContentStyle>{letter.content.slice(0, 35)}...</ContentStyle>}
              </div>
            </LetterStyle>
          )
        })}

    </div>
  )
}

export default Letters

 

Header.jsx

const dispatch = useDispatch()
  const allBtnClickColorhandler = () => {
    setAllbtnColor('greenyellow')
    setIdolbtnColor('white')
    setActorbtnColor('white')
    setSingerbtnColor('white')
    dispatch(
      writeToSelect("아이돌 솔로가수 배우")
    )

  }
  const IdolBtnClickColorhandler = () => {
    setAllbtnColor('white')
    setIdolbtnColor('greenyellow')
    setActorbtnColor('white')
    setSingerbtnColor('white')
    dispatch(
      writeToSelect("아이돌")
    )

  }
  const ActorBtnClickColorhandler = () => {
    setAllbtnColor('white')
    setIdolbtnColor('white')
    setActorbtnColor('greenyellow')
    setSingerbtnColor('white')
    dispatch(
      writeToSelect("배우")
    )

  }
  const SingerBtnClickColorhandler = () => {
    setAllbtnColor('white')
    setIdolbtnColor('white')
    setActorbtnColor('white')
    setSingerbtnColor('greenyellow')
    dispatch(
      writeToSelect("솔로가수")
    )

  }

 

여전히 구린 색 전환을 뒤로한채.. 

적어주었다. 

 

처음 작성해봤을 땐 머리가 단단히 고장났는지 

.filter((L) => {
          return L.writedTo.includes(writeToselect.select)
        })

이따구로 넣고 있었다... 근데 문제 파악을 잘못해서 "엥 왜 writedTo에 접근이 안되지?"이러고 있었다... 이걸로 한참을 실갱이를 하다 발견한 것이다.. 오류가날때 문제파악을 하는 것이 조금 서투른 것 같다. 

 

마지막 제출 전에 리팩토링 해서 제출해야겠다.

 

 

 

목표 달성여부

  • redux
  • 렌더링 최적화하기

내일 목표

  • 렌더링 최적화하기
  • todolist 피드백대로 고쳐보기.