[누구든지 하는 리액트] 7-1. 배열 데이터 렌더링 및 관리(배열에 데이터 삽입하기)

EJ·2020년 12월 30일
0

React

목록 보기
8/12

배열에 데이터 삽입하기

자식 컴포넌트가 부모한테 값을 전달하는 방법을 알아보자.

App 컴포넌트 내부에서 handleCreate 메소드를 만든다. 이 메소드를 자식 컴포넌트(PhonrForm.js)에 props로 전달해주고, props로 전달한 함수를 자식 컴포넌트에서 호출시켜서 data값이 App에 전달되도록 하면 된다.


PhoneForm으로 실습해보자.

App.js에서 handleCreate메서드를 생성해준다.

// App.js
handleCreate = (data) => {
   console.log(data);
}

render() {
    return (
      <div>
        <PhoneForm onCreate={this.handleCreate} />
      </div>
    );
  }
}

PhoneForm.js로 돌아와서 <input />아래에 <button>태그를 생성해준다.

// PhoneForm.js
<button type="submit">등록</button>

<button>을 눌러 submit할 경우 작동할 이벤트를 handleSubmit으로 생성해준다.

// PhoneForm.js
handleSubmit = (e) => {
  e.preventDefault(); // 이벤트 발생 시 새로고침을 방지해준다.

  // App.js에서 props로 받았던 onCreate를 호출해준다.
  this.props.onCreate({
    name: this.state.name,
    phone: this.state.phone
  })
  // this.props.onCreate(this.state)로 작성해도 상관없다.
}

.....
.....

<form  onSubmit={this.handleSubmit}>
.....
</form>

input에 입력 후 [등록]버튼을 눌러 submit하게 되면 콘솔창에서 입력한 값을 확인할 수 있다.

지금까지 작업을 통해 App.js에서 PhoneForm.js의 데이터를 받아올 수 있었다.

이제 PhoneForm.js에서 받아온 데이터를 App.js의 상태에 담아줘보자.

App.js에서 생성했던 handleCreate 메서드를 이용해 받아온 데이터를 state에 넣어준다.

// App.js
class App extends Component {
  // PhoneForm에서 받아온 데이터를 App.js의 상태에 담아줘보자.

  // 1. state를 생성해 information배열을 만들어준다.(이 배열에 받아온 데이터를 넣어줄 것이다.)
  state = {
    information: [],
  }

  handleCreate = (data) => {
    // PhoneForm에서 받아온 데이터를 App.js의 상태에 담아줘보자.
    console.log(data);

    // *** 아래 두 가지 방법처럼 작성하면 안된다!!!
    // this.state.information.push(data)
    // this.setState({
    //   information: this.state.information.push(data)
    // })
    // *** 그 이유: 리액트는 불변성을 유지시켜줘야 한다. 
    // 어떤 값을 수정하게 될 때 꼭 setState를 사용해야 하고, 그 내부에 있는 배열이나 객체를 바꾸게 될 경우 기존의 배열/객체를 바꾸는 것이 아니라 기존의 배열/객체를 기반으로 새로운 배열/객체를 만들어서 값을 주입해줘야한다.
    // 따라서 concat이라는 내장함수를 사용해줘야한다.

    this.setState({
      information: this.state.information.concat(data)
    })
  }

  render() {
    ...
    ...
  }
}

리액트는 불변성을 유지시켜줘야 한다.

어떤 값을 수정하게 될 때 꼭 setState를 사용해야 한다.
내부에 있는 배열이나 객체를 바꾸게 될 경우 기존의 배열/객체를 바꾸는 것이 아니라 기존의 배열/객체를 기반으로 새로운 배열/객체를 만들어서 값을 주입해줘야한다.

따라서 concat이라는 내장함수를 사용해줘야한다.

handleCreate 메서드를 비구조화 문법을 이용해서 보다 간단하고 가독성도 높아지게 수정해주면 좋다.

// App.js
  handleCreate = (data) => {
    const { information } = this.state; // 비구조화 할당 문법을 이용해 handleCreate메서드를 좀 더 간편하게 수정할 수 있다.(코드가 길어지는 것을 방지 + 가독성 높여줌)
    this.setState({
      information: information.concat(data)
    })
  }

PhoneForm.js로 돌아와서 input값을 submit할 경우 기존 입력 값들을 초기화되도록 해주자.

    handleSubmit = (e) => {
        e.preventDefault(); // 이벤트 발생 시 새로고침을 방지해준다.

        // App.js에서 props로 받았던 onCreate를 호출해준다.
        this.props.onCreate({
            name: this.state.name,
            phone: this.state.phone
        })
        // this.props.onCreate(this.state)로 작성해도 상관없다.

        // input값을 submit할 경우 기존 입력 값들을 초기화 시켜주자.
        this.setState({
            name: '',
            phone: '',
        })
    }

이번에는 데이터를 추가할 때마다 각 데이터에 고유한 id값이 들어가도록 해보자.

App.js의 클래스 컴포넌트 상단에 초기 id값을 0으로 입력해준다.

class App extends Component {
  id = 0;
  ...
  ...
}

id값을 state에서 작성하지 않은 이유는 id값은 렌더링되는 값이 아니기 때문이다.

💡 setState를 하는 이유는 어떤 값이 수정되었을 때 리렌더링을 하기 위함이다.

handleCreate 메서드에서 받아온 데이터를 배열에 넣을 때마다 id값이 추가되도록 수정해준다.

  handleCreate = (data) => {
    const { information } = this.state; 
    this.setState({
      information: information.concat({
        ...data, 
        id: this.id++
      })
    })
  }

id값을 넣어준 이유는 배열을 렌더링 할 때 고유한 key값이 필요하기 때문에 넣어준 것이다.

id를 넣어주는 또다른 방법들을 살펴보자.

// 방법 1) 
      information: information.concat(Object.assign({}, data, { 
      // 빈 객체에 data를 넣어주고, 마지막에 적은 {id}도 빈 객체에 넣어주겠다는 의미이다.
        id: this.id++
      }))

// 방법 2)      
      information: information.concat({
        name: data.name,
        phone: data.phone,
        id: this.id++
      })
profile
주니어 프론트엔드 개발자 👼🏻

0개의 댓글

관련 채용 정보