Notice
Recent Posts
Recent Comments
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

HYEWON JUNG의 개발일지

state , state와 불변성, 전개구문을 이용한 불변성 유지 본문

React

state , state와 불변성, 전개구문을 이용한 불변성 유지

혜won 2023. 11. 1. 15:34

state를 쓰는 이유 

UI를 바꾸기 위해서다, 렌더링을 다시하기 위해서

<state 만들기>

const [state, setState]= useState('initial Value')

배열 안의 'state'는 초기값을 받을 변수, 'setState'는 변수를 제어할 메소드 , 'initial Value'는 초기값

 

state를 input에 준다고 했을 때 input 입력값에 따라 state를 변경하려면

<input type='text' 
	value={ID} 
	onChange={function(evnet){setID(evnet.target.value)
  }} />

 

하고 밑에 {ID} 로 나타낼 곳에 넣어주면 되겠죠

 

<불변성과 react의 연관성>

불변하다, 가변하다 참고할 것.

2023.10.27 - [JavaScript] - 데이터 타입 > 얕은 복사 , 깊은 복사

 

데이터 타입 > 얕은 복사 , 깊은 복사

데이터 타입 기본형 Number String Boolean Null undefined symbol 참조형 > Object Array Function Date RegExp Map/WeakMap set / WeakSet 변수 vs 상수 변수 = 변수영역에서 메모리 변경 가능 상수 = 변수영역에서 메모리 변경

hyewonjung-coding.tistory.com

React의 화면 렌더링은 state의 변화가 결정한다.

 

원시 데이터(기본형)=>불변하다 => state가 변화되어 화면에 렌더링도 변한다.

참조형데이터=> 가변하다 => state가 변하지 않아 화면의 렌더링도 변하지 않고 데이터만 바뀐다. 

 

state는 변수 영역의 변화만 볼 수 있다고 생각하면 된다. 

 

그러면 참조형에서 변경사항은 어떻게 해야 state가 볼 수 있을까?

새로운 참조형을 만들어주는 것이다. 이미 데이터영역에 새로운 값이 할당되어있는 상태에서 변경된 상태의 원조 참조형을 복사한 새로운 참조형을 만드는데 참조형 자체를 복사하는 것이 아닌 전개구문으로 참조형 내부의 값만 가져오면, 이미 변경된 값이 데려와지니까 state가 새로운 참조형을 보게 된다면 변경된 값이 렌더링 될 수 있는거죠. 

function App() {
  let [obj, setObj]= useState({
    name: 'hyewon',
    age:24
  })

  return (
    <div>
      <p>{obj.name}</p>
      <button 
      onClick={()=>{
        obj.name = 'hyetwo'
        let obj2 ={...obj}; // 전개구문
        setObj(obj2);
        console.log(obj2)
      }}>클릭</button>
      
    </div>
  )
}

 

왜  원조 참조형을 바로 복사하면 안되는걸까. 직접 코드를 입력해서 구분해봐야겠다.

값이 아예 사라져서 console로 찍어보니 obj2라는 객체에 obj란 객체가 중첩되어 들어간 것을 볼 수 있네요.

## 헉 아님  저건 내가 코드에  obj를 객체로 또 묶고 있었기 때문임  잘못 이해할 뻔

let obj2 ={obj};

이게 제대로 했을 때

그냥 obj로 했을 때와 같이 콘솔에만 바뀐다. 

 

당연하게도 obj가 바라보는 주소값이 변하지 않아서 새 객체를 만들어준건데 그 문제의 객체를 복사하니 같은 문제가 생기는 거죠. 그러니 그 값만 취하는 전개구문으로 새 객체를 생성해서 타파하자!

 

<실습>

+1 버튼을 누르면 +1 되고 -1 버튼을 누르면 -1이 되는 count앱을 만들기!

우선 틀 만들기 -> state 만들기 -> 버튼에 onclick넣기 -> onclick함수 적어주기 순으로 진행했고 

function App() {
  let [count, setCount]= useState(0)
  let plus = ()=>setCount(++count)
  
  
  return (
    <div style=
    {{display:'flex',
      flexDirection:'column',
      justifyContent: 'center',
      alignItems:'center',
      }}>
      {count}
      <div>
        <button onClick={plus}>+1</button> // 이렇게 써도 되고(함수 선언 후 사용)
        <button onClick={()=>setCount(--count)}>-1</button> //이렇게 써도 되고(바로 함수 삽입)
      </div>

    </div>
  )
}

중앙정렬도 해줬다! style쓰는법에 익숙해지려고 !

++count 는 

- 증감 연산자 

변수 ++ 기존 변수의 값에서 1을 더하기
//기존 먼저 불러오고 +1
변수 -- 기존 변수의 값에서 1을 빼기
//기존 먼저 불러오고 -1
++변수 기존 변수의 값에서 1을 더하기
//바로 +1 값 호출
--변수 기존 변수의 값에서 1을 빼기
//바로 -1 값 호출

count++가 되면 안된다! 똑같이 +1이지만 실행되는 시점이 다르다!

 

#class 형 컴포넌트

import React from "react";

class App extends React.Component{
  state={
    count:0,
  }
  add=()=>{
    this.setState(current=>({count: current.count +1,}))
  }
  minus=()=>{
    this.setState(current=>({count: current.count -1,}))
  }
  
  render(){
  return(
    <div>
      <h1>The number is:{this.state.count}</h1>
      <button onClick={this.add}>add</button>
      <button onClick={this.minus}>Minus</button>
    </div>
  )
}
};


export default App;