데이터를 수정하게 될 때에는 .slice함수 또는 .map함수를 사용할 수가 있다.
slice를 수정할 때는 배열을 잘라서 사이에 어떤 것을 넣는식으로 하고
map함수같은경우에는 배열안에 데이터를 모두 제곱할 때 또는 데이터 배열을 리액트 컴포넌트를 변환할 때 전체적으로 변환할 때 사용할 수 있다.
특정조건에 부합할 때만 변경시키고 그렇지 않으면 그대로 유지하는 기능도 가능하다. map함수를 통해서 기능을 익혀보자. n이 3이면 9로 바꿔주고 그렇지 않으면 그대로 numbers값인 n을 출력하게 하면 아래와 같다.
// slice
[
...numbers.slice(0, 2),
9,
...numbers.slice(3, 5)
]
(5) [1, 2, 9, 4, 5]
numbers
(5) [1, 2, 3, 4, 5]
// map
const numbers = [1, 2, 3, 4, 5];
undefined
numbers.map(n => {
if ( n === 3) {
return 9;
}
return n
});
(5) [1, 2, 9, 4, 5]
리액트에서도 구현해보자. App 컴포넌트에서 handleUpdate라는 함수를 만들어 준다. 두 가지 값을 파라미터로 만들어 준다.( id, data) 첫번째 값은 id이고 두번째 값은 값을 어떻게 바꿀지 이다.
비구조할당을 통해 information에 대한 레퍼런스를 가져오고 this.setState하고 information을 넣어주고 information.map을 해준다.
함수도 설정해주는데 info값을 파라미터로 가져와서 info가 가지고 있는 id값이 파라미터로 가져온 id랑 일치한다면
id값은 그대로 해주고 ...data를 해주면서 name과 phone값이 들어가지게 한다. 그리고 true가 아니면 info를 return해준다.
handleUpdate를 PhoneInfoList한테 전달해준다. onUpdate라는 함수로 전달을 해준다.
// App.js
handleUpdate = (id, data) => {
const { information } = this.state;
this.setState({
information: information.map(info => {
if (info.id === id) {
return {
id,
...data
};
}
return info;
})
});
};
render() {
return (
<div>
<PhoneForm onCreate={this.handleCreate} />
<PhoneInfoList
data={this.state.information}
onRemove={this.handleRemove}
onUpdate={this.handleUpdate}
/>
</div>
);
}
}
PhoneInfoList를 열어주고 전달받았던 onUpdate를 그대로 PhoneInfo한테도 전달을 해준다.
// PhoneInfoList.js
const list = data.map(info => (
<PhoneInfo
onRemove={onRemove}
onUpdate={onUpdate}
info={info}
key={info.id}
/>
));
return <div>{list}</div>;
}
}
PhoneInfo.js를 연 다음에 사용해주는 로직을 작성해준다. PhonInfo 컴포넌트에 수정모드를 만들어 줄 것이다.
state를 정해주는데 editing이라는 값을 설정해준다.(기본값은 false)
그리고 handleToggleEdit이라는 함수를 정해주는데 editing값을 반전시켜주는 역할을 한다. 만약 값이 false면 true로 해주고 true이면 false로 해줄 것이다. 값이 실행 될 때마다 반전이 된다.
// PhoneInfo.js
state = {
editing: false,
};
handleToggleEdit = () => {
this.setState({
editing: !this.state.editing,
})
}
<button onClick={this.handleRemove}>삭제</button>
<button>수정</button>
그리고 edit값이 true가 되면 div로 보여주는 것이 아니라 input을 보여줄 것이다. editing이라는 값을 레퍼런스로 만들어주고 상단에서 { component }에서 Fragment라는 것을 불러온다. JSX에서도 사용했었다.
모든 컴포넌트는 <div></div>처럼 감싸져 있어야 하는데 감싸주고 싶은데 추가적인 div를 만들어 주고 싶지 않다. 그러면 Fragment를 사용해도 된다
만약 editing 값이 true이면 뭘 보여줄 것이고 기존에 보여주던 것을 보여준다라고 작성해본다. 그리고 editing이라고 있는데 editing이 있을 때는 input을 2개 만들어 줄것이다. 여기도 Fragement로 감싸준다.
그리고 button에다가 이벤트를 연결해준다. 그리고 각 input을 div로 감싸주면서 세로로 나오게 한다.
수정버튼이 editing된 후면 적용이라고 나타나게 해주기 위해 삼항연산자 { editing ? '적용' : '수정' }이라고 작성해준다.
// PhoneInfo.js
import React, { Component, Fragment } from "react";
return (
<div style={style}>
{editing ? (
<Fragment>
<div>
<input
/>
</div>
<div>
<input
/>
</div>
</Fragment>
) : (
<Fragment>
<div>
<b>{name}</b>
</div>
<div>{phone}</div>
</Fragment>
)}
<button onClick={this.handleRemove}>삭제</button>
<button onClick={this.handleToggleEdit}>
{editing ? "적용" : "수정"}
</button>
</div>
);
}
}
export default PhoneInfo;
state에다가 name값과 phone값을 넣어주고 handleChange도 구현을 해준다. handleChange를 input에다가 연결도 해준다. value값도 설정을 해주고 name도 넣어준다.
// PhoneInfo.js
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
return (
<div style={style}>
{editing ? (
<Fragment>
<div>
<input
name="name"
onChange={this.handleChange}
value={this.state.name}
/>
</div>
<div>
<input
name="phone"
onChange={this.handleChange}
value={this.state.phone}
/>
</div>
그리고 ToggleEdit에서 editing값이 반전될 때 name값이 처음에는 공백이고 적용을 했을 때 수정된 값이 기본값으로 되기 위해서 handleToggleEdit에서 로직을 작성해주어야 한다. 첫번째로 true에서 false로 전환될 때 전달받았던 onUpdate함수를 전달받아서 update하겠다라고 부모 컴포넌트에 알린다.
false에서 true로 전환될 때는 props로 받아왔던 info안에 있는 name과 phone값을 state쪽에 넣어주는 작업을 해준다.
일단 비구조화 할당을 info값과 onUpdate값에 대한 레퍼런스를 만들어준다. 만약 현재 editing값이 true이다 그러면 false로 전환이 되는 것인데 onUpdate에서 첫번째 파라미터인 info.id, 두번째에는 어떻게 업데이트 할 지에 대한 정보인 현재 들고있는 state를 담아준다.
그리고 else 즉 현재 false에서 true로 전환이 된다면 this.setState를 통해서 name값은 info.name, phone값은 info.phone으로 해준다.
// PhoneInfo.js
class PhoneInfo extends Component {
state = {
editing: false,
name: "",
phone: ""
};
handleToggleEdit = () => {
// true -> false
// onUpdate
// false -> true
// state 에 info 값들 넣어주기
const { info, onUpdate } = this.props;
if (this.state.editing) {
onUpdate(info.id, {
name: this.state.name,
phone: this.state.phone
});
} else {
this.setState({
name: info.name,
phone: info.phone
});
}
this.setState({
editing: !this.state.editing
});
};
리액트의 state에 있는 배열 안의 값을 수정하는 것도 알아보았다. 배열과 객체값을 직접 수정하면 안되고 불변성을 유지하면서 데이터를 새로 생성하는 방식으로 해야하는지도 배워보자.
<출처 : velopert(김 민준) 누구든지 하는 리액트: 초심자를 위한 react 핵심 강좌>
https://www.inflearn.com/course/react-velopert/dashboard
누구든지 하는 리액트: 초심자를 위한 react 핵심 강좌 - 인프런 | 강의
리액트를 누구든지 쉽고 재밌게 시작 할 수 있도록 만들어진 강좌입니다., React 핵심 강좌 초심자를 위한 리액트(React) 핵심 강좌입니다. 만약에 여러분이 리액트를 배우고 싶은데, 아직 뭐가 뭔
www.inflearn.com
'React > velopert_react' 카테고리의 다른 글
shouldComponentUpdate를 통한 최적화, 불변성을 왜 유지하는가? (0) | 2021.08.22 |
---|---|
배열에서 데이터 제거하기 (0) | 2021.08.20 |
배열 렌더링하기 (0) | 2021.08.20 |
배열에 데이터 삽입하기(배열 데이터 렌더링 및 관리) (0) | 2021.08.20 |
Input 상태 관리하기 (0) | 2021.08.19 |