[React] 노마드코더 - React의 State

김지원·2023년 1월 11일
0

Frontend

목록 보기
5/28

💡React의 State

state는 기본적으로 데이터가 저장되는 곳이다.
어떻게 하면 React.js 어플에 값이 바뀔 데이터를 담아줄 수 있을까?

📌 Data를 담고 Update하는 방법

🚩 좋지 않은 방식

변수들을 JSX로 보내주는 방법은?

        let counter = 0;
        const Container = () => (
            <div>
                <h3>Total Clicks: {counter}</h3>
                <button>Click me</button>
            </div>
        );

counter을 증가시키는 UI를 만드려면?

        let counter = 0;
        function countUp() {
            counter = counter + 1;
        }
        const Container = () => (
            <div>
                <h3>Total Clicks: {counter}</h3>
                <button onClick={countUp}>Click me</button>
            </div>
        );

하지만 위 코드로는 UI가 변하지 않는다. counter 변수는 update되지만, UI를 새로고침해주고 있지 않다.렌더링을 한 번만 해주기 때문이다.

즉, Container를 리렌더링해서 새로운 버전의 Container을 보여줘야 한다.

    <script type="text/babel">
        const root = document.getElementById("root");
        let counter = 0;
        function countUp() {
            counter = counter + 1;
            render(); // Container을 리렌더링해줌
        }
        function render() {
            ReactDOM.render(<Container />, root);  
        }
        const Container = () => (
            <div>
                <h3>Total Clicks: {counter}</h3>
                <button onClick={countUp}>Click me</button>
            </div>
        );
        render(); // app이 시작될 때 Container 렌더링
    </script>

❓왜 최고의 방법이 아닌가?

counter의 값을 바꿀 때마다 다시 렌더링하는걸 잊으면 안 되기 때문이다!

🚩 Professional한 react 방식

React.js 앱 내에서 데이터를 보관하고 자동으로 리렌더링할 수 있는 최고의 방법은?

        const root = document.getElementById("root");
        function App() {
            // 아래처럼!!! 이렇게!!
            const [counter, modifier] = React.useState(0);           
           //
            return (
                <div>
                    <h3>Total Clicks: {counter}</h3>
                    <button>Click me</button>
                </div>
            );
        }
        ReactDOM.render(<App />, root);  

modifier

👉modifier 함수는 어떤 값을 부여하던 그 값으로 업데이트하고 리렌더링을 일으킨다. component가 재생성되는 원리임.

  • 보통 set{데이터이름} 형태로 이름을 부여한다.
  • 데이터를 수정하기 위해 modifier 함수를 사용한다면, 그 modifier 함수를 사용할 때 컴포넌트는 새로운 데이터와 함께 새로고침된다.
        function App() {
            const [counter, setCounter] = React.useState(0);            
            const onClick =() => {
              // 여기 modifier 함수!!!
                setCounter(counter+1);
            };
            return (
                <div>
                    <h3>Total Clicks: {counter}</h3>
                    <button onClick={onClick}>Click me</button>
                </div>
            );
        }

modifier 함수를 사용해 state, 즉 어플리케이션의 데이터를 바꿀 때, 컴포넌트 전체가 새로운 값을 가지고 재생성된다.

👉 state가 바뀌면 리렌더링이 일어난다.

❓ State Function - state을 바꾸는 또다른 방법은?

  1. setCounter 이용해서 원하는 값을 넣어주기
    이 방법은 현재 counterstate를 이용해서 새로운 counterstate를 계산한다.
    ❗❗ 하지만 counter는 다른 곳에서도 변경될 수 있다는 점!
setCounter(counter+1);
  1. 현재 state를 기반으로 다음 state를 계산
setCounter((current) => current + 1);

이처럼 현재 state를 기반으로 다음 state를 계산하고 싶다면 함수를 이용하면 된다!

💡 Inputs and State

사용자의 input을 어떻게 얻는지, form을 만들었을 때 state는 어떤식으로 작용하는지?

⌨️ Unit Converter 만들기

labelinput 옆에 써주는 글씨다.

        function App() {
            return (
                <div>
                    <h1>Super Converter</h1>
                    <label for="minutes">Minutes</label>
                    <input id="minutes" placeholder="Minutes" type="number" />
                    <label for="hours">Hours</label>
                    <input id="hours" placeholder="Hours" type="number"/>
                </div>
            );
        }

위를 jsx 방식으로 바꿔줘야 한다.
예를 들어 for, classjavascript 용어이기 때문이다.

        function App() {
            const [minutes, setMinutes] = React.useState();
            const onChange=()=>{
                console.log("somebody wrote");
            };
            return (
                <div>
                    <h1 className="hi">Super Converter</h1>
                    <label htmlFor="minutes">Minutes</label>
                    <input 
                      // 이를 통해 어디서든 input의 value를 수정할 수 있다.
                        value={minutes} 
                        id="minutes" 
                        placeholder="Minutes" 
                        type="number" 
                        onChange={onChange}/>
                    <label htmlFor="hours">Hours</label>
                    <input id="hours" placeholder="Hours" type="number"/>
                </div>
            );
        }

React.useState()는 array를 return하는데, 첫 번째 item은 value이고, 두 번째 item은 이 value를 수정하고, component를 새로고침 할 때 쓰는 함수이다.

위의 경우, 👉변화를 감지하면(onChange), onChange 함수가 실행된다.

        function App() {
            const [minutes, setMinutes] = React.useState();
            const onChange=()=>{
              // event.target.value로 input에 들어온 값에 접근할 수 있다!
                setMinutes(event.target.value);
            };
            return (
                <div>
                    <h1 className="hi">Super Converter</h1>
                    <label htmlFor="minutes">Minutes</label>
                    <input 
                        value={minutes} 
                        id="minutes" 
                        placeholder="Minutes" 
                        type="number" 
                        onChange={onChange}/>
                	<h3>You want to convert {minutes}</h3>

                    <label htmlFor="hours">Hours</label>
                    <input id="hours" placeholder="Hours" type="number"/>
                </div>
            );
        }
  • inputvalue를 연결시켜주는 이유는 input값을 외부에서도 수정해주기 위해서이다.
  • onChange 함수는 변화를 감지하고 데이터를 업데이트 시켜주기 위함이다.

이제 hours 부분도 수정해보자.

        function App() {
            const [minutes, setMinutes] = React.useState();
            const onChange=(event)=>{
                setMinutes(event.target.value);
            };
            return (
                <div>
                    <h1 className="hi">Super Converter</h1>
                    <div>
                        <label htmlFor="minutes">Minutes</label>
                        <input 
                            value={minutes} 
                            id="minutes" 
                            placeholder="Minutes" 
                            type="number" 
                            onChange={onChange}/>
                    </div>
                    <div>
                        <label htmlFor="hours">Hours</label>
                        <input 
                            value={minutes/60} 
                            id="hours" 
                            placeholder="Hours" 
                            type="number"/>
                    </div>
                    
                </div>
            );

⌨️ Unit Converter 만들기 - flip function

state 값에 따라 inputenabled 할지, disabled 할지 결정할 수 있다.

flipped의 default 값은 false이다.

  • flipped 상태라면 state에 있는 값 그대로 보여주기
  • flipped 상태가 아니라면 단위 변환된 값 보여주기
  • false인 경우: 분=>시 변환, hoursdisabled=true
value={flipped ? amount : Math.round(amount/60)} 
  • true인 경우: 시=>분 변환, minutesdisabled=true
value={flipped ? amount * 60 : amount} 

이처럼 React는 state를 바탕으로 UI를 변경할 수 있는 유용한 언어이다.

  • component는 그 안에 또 다른 component를 렌더링할 수 있다.
        function MinutesToHours() { ...
        function App() {
            return (
                <div>
                    <h1>Super Converter</h1>
                    <MinutesToHours />
                </div>
            );
        }
  • {} 안에는 javascript를 작성할 수 있다.

input이 있고, 그리고 변화가 일어나면 state를 업데이트 한다.

profile
Make your lives Extraordinary!

0개의 댓글