DEVLOG

React 배열 관리하기 :: 생성과 렌더링 (+concat/slice/map/filter개념) 본문

frontend/react

React 배열 관리하기 :: 생성과 렌더링 (+concat/slice/map/filter개념)

meroriiDev 2020. 11. 2. 17:26
728x90
반응형

*주의

리액트에서 배열을 다룰 때 평소 하던것처럼...

push를 사용해서~ this.state.array.push('some value'); 이렇게 하면 되겠지?하면 절대XXX

 

why??

리액트에서는 state내부의 값을 직접적으로 수정하면 안되기 때문! (불변성 유지)

push, splice, unshift, pop 같은 내장함수는 배열 자체를 직접 수정하게 되므로 적합하지 않다.

 

then??

기존 배열에 기반하여 새 배열을 만들어내는 함수인 concat, slice, map, filter와 같은 함수를 사용해야한다.


.concat()

: 기존 배열에 원소 또는 배열을 추가하여 새 배열을 만들 수 있다.

var arr2 = arr1.concat( 'abc' );

=> arr1배열에 문자열 abc를 추가하여 arr2배열을 만듬.

var arr3 = arr1.concat( arr2 );

=> arr1배열과 arr2배열을 합하여 새로운 arr3배열을 만듬

 

.slice()

: begin부터 end전까지의 본사본으로 새 배열을 만들 수 있다.

slice(start[, end])

start : 추출 시작점 인덱스

  • undefined인 경우 : 0부터 slice
  • 음수인 경우 : 배열의 끝에서부터의 길이( slice(-2)이면 배열의 마지막 2개의 요소를 추출)
  • 배열의 길이와 같거나 큰 수인 경우 : 빈 배열을 반환

end : 추출을 종료할 기준 인덱스(end를 제외하고 그 전까지만 추출)

  • undefined인 경우 : 배열의 끝까지 slice
  • 음수인 경우 : 배열의 끝에서부터의 길이를 나타낸다. ( slice(2, -1)이면 세번째부터 끝에서 두번째 요소까지 추출)
  • 배열의 길이와 같거나 큰 수인 경우 : 배열의 끝까지 추출

.map()

: 콜백함수의 리턴을 모아서 새로운 배열을 만들 수 있다.

: 요소를 일괄적으로 변경하는데 효과적임

// 문자열 배열에서 문자열 길이만 획득하기
var arr = ['foo', 'hello', 'diamond', 'A'];
var arr2 = arr.map(function (str) {
    return str.length;
});
console.log(arr2); // [3, 5, 7, 1]

.filter()

: 콜백함수의 리턴을 모아서 새로운 배열을 만들 수 있다.

: 요소들을 걸러내기 위한 목적

// 정수 배열에서 5의 배수인 정수만 모으기
var arr = [4, 15, 377, 395, 400, 1024, 3000];
var arr2 = arr.filter(function (n) {
    return n % 5 == 0;
});
console.log(arr2); // [15, 395, 400, 3000]

리턴값은 boolean으로 리턴이 true인 요소만 모아서 새로운 배열을 만든다.

때문에 만족하는 요소가 없다면 undefined가 아닌 빈 배열이 반환된다.


PhoneForm.js

import React, {Component} from 'react';

class PhoneForm extends Component{
    state={
        name:'',
        phone:''
    }
    handleChange=(e)=>{
        this.setState({
            //name:e.target.value     //이벤트 객체에 담겨있는 텍스트값 읽어옴(이름 하나만 테스트할때)
            [e.target.name]: e.target.value //두가지 이상 ==> *Computed property names문법
        });
    }
    handleSubmit=(e)=>{
        e.preventDefault(); //submit이 발생하면 페이지가 리로딩되는데 이것을 방지하기 위함
        this.props.onCreate(this.state);    //상태값 부모에게 전달
        this.setState({     //초기화
            name:'',
            phone:''
        })
    }
    render(){
        return(
            <form onSubmit={this.handleSubmit}>
                <input 
                    placeholder="이름" 
                    value={this.state.name}
                    onChange={this.handleChange}    //변할때마다 handleChange함수사용해서 텍스트값을 읽어오는 방식
                    name="name"
               />
                <input
                    placeholder="전화번호"
                    value={this.state.phone}
                    onChange={this.handleChange}
                    name="phone"
                />
                <button type="submit">등록</button>
            </form>
        );
    }
}

export default PhoneForm;

PhoneInfo.js

import React, {Component} from 'react';

class PhoneInfo extends Component{
    static defaultProps = {
        info:{			
            name: '이름',
            phone: '010-0000-0000',
            id:0		//info의 기본값 설정 (*info가 undefined일 경우 비구조화 할당을 통해 내부의 값을 받아올 수 없어서 컴포넌트가 크래쉬되기때문)
        }
    }
    
    render(){
        const style={		//css style 
            border:'1px solid black',
            padding:'8px',
            margin:'8px'
        };
        const {		
            name, phone, id
        } = this.props.info;

        return(
            <div style={style}>		//위에서 선언한 style적용
                <div><b>{name}</b></div>
                <div>{phone}</div>
            </div>
        )
    }
}

export default PhoneInfo;

PhoneInfoList.js

import React, {Component} from 'react';
import PhoneInfo from './PhoneInfo';

class PhoneInfoList extends Component{
    static defaultProps={
        data:[]
    }
    
    render(){
        const {data} = this.props;
        const list = data.map(
            info => (<PhoneInfo key={info.id} info={info}/>)
        ); /data배열을 가져와 map을 통해 JSX로 변환하는 과정
        return(
            <div>
                {list}
            </div>
        )
    }
}

export default PhoneInfoList;

App.js

import React, {Component} from 'react';
import PhoneForm from './components/PhoneForm';
import PhoneInfoList from './components/PhoneInfoList';

class App extends Component{
  id=2
  state = {
    information:[
      {
        id:0,
        name:'시메송',
        phone:'010-0000-0000'
      },
      {
        id:1,
        name:'룰룰루',
        phone:'010-0000-0001'
      }
    ]
  }
  handleCreate = (data)=>{
    const {information} = this.state;	//초기저장값
    this.setState({		//변화된 값
      information: information.concat({id:this.id++, ...data})	//...data는 받아온 data그대로
    })
  }

  render(){
    const {information}=this.state;	
    return(
      <div>
        <PhoneForm
          onCreate={this.handleCreate}
        />
        <PhoneInfoList data={this.state.information}/>
      </div>
    );
  }
}

export default App;

결과

이해가 갈듯말듯....어렵다ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

이해는 가지만 짜라고 하면 아무것도 못할 것 같은 고런 상황..


* computed property names 문법

: 표현식(expression=>변수,함수 등..)을 이용해 객체의 key값을 정의하는 문법

 

728x90
반응형

'frontend > react' 카테고리의 다른 글

React 프로젝트 :: TodoList 따라하기  (0) 2020.11.16
React 배열 관리하기 :: 제거와 수정  (0) 2020.11.02
React LifeCycle  (0) 2020.10.14
React의 데이터 :: props와 state  (0) 2020.10.13
React 시작하기  (0) 2020.10.13
Comments