류림스 공간

[항해99 24일차] 2022.03.30 TIL /수정기능 본문

TIL/2022 TIL

[항해99 24일차] 2022.03.30 TIL /수정기능

ryurim 2022. 3. 30. 22:14
반응형

<오늘 할 일>

1. 무한스크롤 or 수정기능구현

2. 알고리즘 문제 풀기

3. 자바스크립트 기초 문법 TIL에 정리하기

4. 회사 리스트업

 

아.. 어제 ,, 누웠는데 잠이 안와서 새벽 한시쯤 잤더니 

넘 넘 피곤스하다. 🤨

블로그..항해99TIL검색하니까..

너무 열심히 하시는 분들이 많아서 자극받았다...!!!

수정 기능은 꼭 구현해야지 !

 

수정 기능을 위한...덕스구조 js

//액션타입
const MODIFY='word/MODIFY'; //댓글 수정 기능

//액션 크리에이터
export function modifyWord(word_index,edit){
    return{type:MODIFY,word_index, edit}
};
//미들웨어는 아직;;

//리듀서
      case "word/MODIFY":{
          const new_word_list = state.list.map((l,idx) => {
            if(parseInt(action.word_index)===idx){
              return{...l,...action.edit};
            }else{
              return l;
            }
          });
          return{list: new_word_list}
      };

app.js

import React from 'react';
import { Route,Switch } from 'react-router-dom'
import './App.css' //reset.css
//page
import Main from './components/Main';
import Header from './components/Header';
import WordAdd from './components/WordAdd';
import NotFound from './components/NotFound';
import Modify from './components/Modify';
//로드할때 필요, 리덕스 업데이트 훅
import {loadWordFB} from './redux/modules/word';
import { useDispatch } from "react-redux";



function App() {
  const dispatch = useDispatch();

  React.useEffect(() => {
    dispatch(loadWordFB());
  }, [dispatch]); //이거 안써주면, 화면에 단어 안붙음 디스패치 빼면, 무한루프에 빠짐..
  
  return (
    <div className="App">
      <Header />
      <Switch>
        <Route path ="/" exact component={Main}/>
        <Route path ="/word/add"  component={WordAdd}/>
        <Route path ="/modify/:word_id" component={Modify} />
        <Route component={NotFound} />
      </Switch>
    </div>
  );
}

export default App;

Modify라는 컴포넌트를 새로 하나 만들었다.

카드 붙는 메인 js에 버튼 하나를 추가해줬다.

 <Link to={{
                                pathname:'/modify/'+words[idx].id,
                                state:{id:words[idx].id,
                                        word:words[idx].word,
                                        desc:words[idx].desc,
                                        example:words[idx].example,
                                        completed:words[idx].completed
                                }
                            }}>
                                <button style={{backgroundColor: list.completed ?"#123389":"#e4ebfb"}}>
                                    <HiPencilAlt style={{color: list.completed ?"#fff":"#123389",
                                        width:"30px",height:"30px" }}/>
                                </button>
                            </Link>

수정 js

import React from "react";
import styled from "styled-components";
import { useHistory, useLocation} from "react-router-dom";
import { useDispatch } from "react-redux";
import { modifyWord } from "../redux/modules/word";


const Modify = (props) =>{

    const location =useLocation();
    const dispatch =useDispatch();
    const history =useHistory();

    const word = React.useRef(null); //초기값은 null 단어
    const desc = React.useRef(null); //초기값은 null 설명
    const example = React.useRef(null); //초기값은 null 예시

    const stateId=location.state.id;
    const stateWord=location.state.word;
    const stateDesc=location.state.desc;
    const stateEx=location.state.example;
    const stateCom=location.state.completed;
    
   
        

     

    const editWord =()=>{

        dispatch(
            modifyWord(stateId,{
                 word: word.current.value.trim(),
                desc: desc.current.value.trim(),
                example: example.current.value.trim(),
                completed:stateCom
            })
            
        )
        history.push("/");
    }

    
    return (
        <>
        <AddOutter>
            <div>
                <h3>단어 수정하기</h3>
                <WordBox>
                    <div>
                        <label>단어</label>
                        <input type="text" ref={word} defaultValue={stateWord}/> 
                    </div>
                    <div>
                        <label>설명</label>
                        <input type="text" ref={desc} defaultValue={stateDesc}/>
                    </div>
                    <div>
                        <label>예시</label>
                         <input type="text" ref={example} defaultValue={stateEx}/> 
                    </div>
                    <button type="submit" onClick={editWord}>단어 수정</button>
                </WordBox>
            </div>
            
        </AddOutter>
    </>
    );
}
//스타일
const AddOutter=styled.section`
    width:100%;
    position:relative;
    top:80px;
    height:100%;
    padding:60px;
    display:flex;
    justify-content:center;
    
    @media screen and (max-width: 500px){
        top:60px;
        }

        & > div{
            width:400px;
            min-height: 70vh;
            background: #e4ebfb;
            border-radius:8px;
            position:relative;
        }
        & > div> h3{
            width: 100%;
            text-align:center;
            font-size: 36px;
            padding:10px;
            font-family:"Dongle";
            @media screen and (max-width: 500px){
                font-size: 30px;
            }
        }
`;
const WordBox =styled.div`
            width:100%;
            height:320px;
            display:flex;
            flex-direction:column;
            justify-content:center;
            align-items:center;
            gap:50px;

        & div {
            
        }
        & label{
            font-family:"Dongle";
            font-size:32px;
            margin-right:10px;
        }
        & input{
            width:200px;
            height:40px;
            border: 1px solid #97ACE3;
            border-radius:5px;
        }
        & input:focus {
            border: 1px solid #123389;
        }
        & > button {
            width:150px;
            height:40px;
            font-family:"Dongle";
            font-size:32px;
            cursor:pointer;
            border-radius:5px;
            background:#97ACE3;
            color:#123389;
        }
        & > button:hover{
            background:#123389;
            color:#97ACE3;
        }
`;

export default Modify;

일단 미들웨어 안 만들었더니 수정한 것이 새로운 단어로 추가되는 현상이 발생..ㅋㅋㅋㅋㅋ

//미들웨어

export const modifyWordFB=(id,newWord) =>{ //단어 수정 id값과 새로운 단어를 받아온다.
    return async function(dispatch,getState){
      const docRef=doc(db,"word",id);
      //console.log(id,newWord)
      await updateDoc(docRef,{...newWord})

      const _word_list=getState().word.list; //getstate사용해서 word에 있는 리스트 정도 긁어오고,
      const word_index =_word_list.findIndex((w)=>{
        return w.id === id; //리스트 안에 id가 파라미터 id와 일치하다면 그친구의 idex 가져와
      });
      const newdata = {...newWord, id:id}
      dispatch(modifyWord(word_index,newdata));
    };
};

이렇게 했더니 수정도 잘된다.ㅠㅠ

감격..물론 내가 짠 건 아니고...코드 보면서했당..

하핫..

음 일단 여기까지 했으니까...무한 스크롤은 미뤄두고,,

노마드 코더 강의..중에서 트워터 클론 코딩 강의가 있는데 무료로 들을 수 있어서 한번 ..들어보겠다 !!!

듣기전에 리액트 훅부터 잘 알아야될 것같아서..

실전형 리액트 HOOKS 10개 강의를 듣겠다 !

 

 

이 사이트에서 하면 리액트 환경설정은 따로 하지 않아도 된다.

hooks은 react의 state machine에 연결하는 기본적인 방법이다.

음 이걸 보다가..항해톡하고, 매니저님과 마일스톤 하니까 시간이 10시가 되어버렸다.

 

일단 단어 추가하기 눌렀을 때 아래에 붙는게 아니라 맨 위에 붙게 하고 싶었는데,

그건 성공했다.. 기술 매니저님 덕분에 !!!!

  case "word/CREATE": {
        const new_word = [ action.word, ...state.list]; // 순서 바꿔서 최근 word가 앞에 붙게 !!
        return { list: new_word };
      }

리듀서 케이스 문에서 action.word를 앞에 붙여주면,, 되었다.

이렇게 간단한 걸  나는 생각하지 못했다.ㅠㅠ

아마도 덜 이해해서 그렇겠지???

 

완성본이다 !!

이제 배포만 하면 끝~!

과제 깃헙 링크 gogo ☄️

728x90
반응형
Comments