[ToyProject-Todomate] 투두메이트 클론 프로젝트 29

2022. 1. 16. 18:31WEB Dev/ToyProject

728x90


🔷 CloneTodo ☑ - Todomate Clone Project  |  Team CloneMate

 

CloneTodo : 많은 사람들이 사랑하는 투두메이트를 클론하여 웹 서비스를 배포해보는 프로젝트

 


 

id값 전달하기

 

 

지금부터 할 것은 어제 GoalEditForm의 TextField에 기존 title이 올라가도록 만들었으니

이제 id값도 전달해서 해당 id값과 goal state를 비교해서 업데이트 해주는 코드를 만들려고 한다.

 

 

 

 

Goals 컴포넌트에서 editEventHandler를 통해 전달된 id 값을 통해 GoalEditForm에 title이 전달되는데

이 때 id 값도 같이 전달되고, 이 아이디값을 가진 state를 만들어 줄 수 있도록 함수를 만들자.

 

 

 

 

 

 

GoalForm에서는 newGoalItem 이라는 새로운 state를 생성해준다.

그리고 TextField 값의 변화를 onInputChange 함수에서 인식해주고 

이 newGoalItem 의 title에 TextField의 값을 넣어주고, newGoalItemChange라는 state 변경 함수로 state가 반영되게 된다.

(기존에 만들었던 것과 변수명을 조금 다르게 변경)

 

 

import { Button, Grid, Box, TextField } from "@mui/material";
import React, { useState } from "react";


export default function GoalForm(props){

    /* props 선언 시작 */

    const addGoal = props.addGoal;

    /* props 선언 끝 */


    /* Hook 선언 시작 */

    let [newGoalItem, newGoalItemChange] = useState({item : { title : '' }}, addGoal);

    /* Hook 선언 끝 */


    /* 함수 선언 시작 */

    function onInputChange(e) {
        const newItem = newGoalItem.item;
        newItem.title = e.target.value;
        newGoalItemChange({item : newItem})
    }

    function onButtonClick(){
        addGoal(newGoalItem.item);
        newGoalItemChange({item : {title: ''}});
    }
    
    function enterKeyEventHandler(e){
        onButtonClick();
    }

    /* 함수 선언 끝 */


    return(
        <Box style={{ margin : 16, padding: 16, position:'relative' }}>
            <Grid container>
                <Grid xs={11} md={11} item style={{paddingRight: 12}}>
                    <p className="goalform_title" style={{fontSize: '12px', color: '#aeaeae'}}>제목</p>
                    <TextField fullWidth id="goalform_textfield" variant="standard" onChange={onInputChange} /> 
                </Grid>
                <Grid xs={1} md={1} item >
                    <Button fullWidth color="secondary" onClick={onButtonClick} 
                    value={newGoalItem.item.title} onKeyPress={enterKeyEventHandler}
                    style={{position:'relative', top: '-85px',  fontSize: '14px', fontWeight: '600', color: '#111'}} >
                        확인
                    </Button>    
                </Grid>
            </Grid>
        </Box>
    )

}

 

 

 

 

변경되는 title을 담을 editGoalItem state 만들기

 

 

 

동일하게 GoalEditForm에서도 newGoalItem대신 editGoalItem으로 state를 생성해주는데, title과 id 를 key로 가질 수 있도록 한다.

 

 

let [editGoalItem, editGoalItemChange] = useState({item : { id: '' , title : '' }});

 

 

그리고 TextField에 연결된 onInputChange를 통해 editGoalItem을 변경해준다.

TextField에서 바뀐 e 값이 들어오는데 editItem 이라는 변수로 선언해둔 state를 카피해주고

editItem.title에 e.target.value를 넣어주고, editItem.id 에 e.target.id를 넣어준다.

id 는 일종의 키 값을 한다. title이 변경되기 때문에 기존 goal state에서 저장된 내용을 찾기 위해서는 id값이 반드시 필요하다.

 

 

function onInputChange(e) {
    const editItem = editGoalItem.item; // editGoalItem state copy
    editItem.title = e.target.value; // TextField에서 받아온 value
    editItem.id = e.target.id;  
    editGoalItemChange({item : editItem})
}

 

 

여기서 함수를 실행해보면 id값이 없다는 오류가 계속 뜰 것이다.

 

현재 TextField 부분에는 id 속성이 없다.

그렇기 때문에 App.js 에 있는 TextField value 변경함수에서 id도 만들어 질 수 있도록 값을 전달해야 한다.

 

 

  //TextField id, value 변경 함수

  function TextFieldControl(currentEditItems) {
    const TextField = document.querySelector("#goaleditform_textfield");
    TextField.value = currentEditItems[0].title;
    TextField.id = currentEditItems[0].id;
  }

 

 

그리고 다시 실행해서 콘솔로 editItem을 찍어보면 다음과 같이 출력된다.

 

 

 

 

 

이제 이 editItem이라는 state를 editGoal이라는 함수를 만들어서 goal state에 반영해주면 된다.

editGoal은 addGoal 과 크게 다르지 않겠지만 id를 한 번 검증하고, 해당 id값에 맞는 title을 바꿔줘야 한다.

id 값을 가지고는 있지만 앞에 'ID-' 라는 접두사가 붙기 때문에, findIndex를 통해 해당 id 값이 몇 번째 인덱스 객체인지 확인하고 해당 객체의 title값을 변경해주면 되겠다.

 

 

 

 

onButtonClick 함수 만들기

 

 

App.js 에 가서 editGoal 함수를 만들어준다. 그리고 GoalEditForm에 props로 함수를 전달해준다.

GoalEditForm에 props로 받아온 함수를 변수에 할당해준다.

 

<Route exact path="/goals">
<BasicNavBar/>
{
  readOnly === 'read' ? <GoalForm addGoal={addGoal} /> : <GoalEditForm editGoal={editGoal} />
}
  <Goals goal={goal.items} addGoal={addGoal} deleteGoal={deleteGoal} editToGoalForm={editToGoalForm} readOnly={readOnly} readOnlyChange={readOnlyChange}  />
</Route>

 

/* props 선언 시작 */

const editGoal = props.editGoal;

/* props 선언 끝 */

 

 

그리고 addGoal 함수를 실행했던 방법처럼 onClickButton 이라는 함수를 만들어주고 버튼에 바인딩해준다.

그리고 함수 내부에 콜백으로 editGoal 함수를 연결해준다.

이 때 editGoal 함수에 인자로 수정한 item이 있는 editGoalItem.item을 넣어준다.

 

 

function onButtonClick(){
    editGoal(editGoalItem.item);
}

 

 

이제 editGoal이라는 함수를 만들어야 한다..!

 

 

728x90