[ReactJS로 영화 웹 서비스 만들기] 02. State

박지원 ·2023년 2월 22일
0
post-thumbnail

1. Understanding State

ReactJS랑 그냥 JS의 차이점을 보면, JS는 무언가 변화가 있으면 변화가 있는 모든 element가 변화한다(total click이 들어있는 span, span이 들어있는 body 모두 변화) 하지만 React는 ui에서 변화가 있는 부분만 업데이트 된다.

React

<!DOCTYPE html>
<html lang="en">

<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    function countUp(){
        counter = counter +1;
        render();
    }
    function render() {
        ReactDOM.render(<Container />, root);
    }
    const Container = () => (
        <div>
            <h3>Total clicks: {counter}</h3>
            <button onClick={countUp}>Click me</button>
        </div>
    );
    ReactDOM.render(<Container />, root);
</script>
</html>

2.setState

React.useState 함수는 (data, function)을 인자로 받음
따라서 이걸 counter(=data), modifier(=function)에 집어넣음

<!DOCTYPE html>
<html lang="en">

<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    
    function App() {
        const [counter, modifier] = React.useState(0);
        console.log(data);
        return (
            <div>
            <h3>Total clicks: {counter}</h3>
            <button>Click me</button>
        </div>
        )
    }
    ReactDOM.render(<App />, root);
</script>
</html>

이제는 function 하나하고 한 줄로 앞에서 구현한 모든 기능들이 가능해짐.

<!DOCTYPE html>
<html lang="en">

<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
    const root = document.getElementById("root");
    function App() {
        const [counter, setCounter] = React.useState(0);
        const onClick = () => {
            setCounter(counter+1);
        };
        return (
          <div>
            <h3>Total clicks: {counter}</h3>
            <button onClick={onClick}>Click me</button>
          </div>
        )
    }
    ReactDOM.render(<App />, root);
</script>
</html>

React의 장점
1. HTML 요소를 생성하거나 찾을 필요가 없음
2. eventListener을 더해줄 필요도 없고, UI를 업데이트 해줄 필요도 없음

3 State Function

하지만 저렇게 counter를 조작한다면, 나중에 원치 않은 곳에서 counter가 변화될 수 있음
따라서 react에서 지원해주는 안전한 함수를 사용해봄

<!DOCTYPE html>
<html lang="en">
<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
    const root = document.getElementById("root");
    function App() {
        const [counter, setCounter] = React.useState(0);
        const onClick = () => {
            //setCounter(counter+1);
            setCounter((current) => current + 1);         
        };
        return (
          <div>
            <h3>Total clicks: {counter}</h3>
            <button onClick={onClick}>Click me</button>
          </div>
        )
    }
    ReactDOM.render(<App />, root);
</script>
</html>

setCounter((current) => current + 1);
이 함수는 언제나 현재 state를 얻도록 해줄 것임

4. State Practice

시간 변환기

분을 시간으로, 시간을 분으로 바꾸는 계산기

<!DOCTYPE html>
<html lang="en">

<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
    const root = document.getElementById("root");
    function App() {
        const [amount, setAmount] = React.useState(0);
        const [flipped, setFlipped] = React.useState(false);

        const onChange = (event) => {
            setAmount(event.target.value);
        };
        const reset = () => setAmount(0);
        const onFlip = () => {
            setFlipped((current) => !current);
            reset();
        }  
        return (
          <div> 
            <h1 className="hi">Super Converter</h1>
            <div>
                <label htmlFor = "minutes" >Minutes: </label>
                <input 
                   value={flipped ? amount*60 : amount} 
                   id = "minutes" 
                   placeholder = "Minutes" 
                   type = "number"
                   onChange={onChange}
                   disabled={flipped}
                />
            </div>
            <div>
                <label htmlFor = "hours">Hours: </label>
                <input 
                   value={flipped ? amount: amount/60} //Flipped 상태라면 단위변환 보여주지 말라는 뜻 
                   id = "hours" 
                   placeholder = "Hours" 
                   type = "number"
                   disabled={!flipped}
                   onChange={onChange}
                />
            </div>
            <button onClick={reset}>Reset</button>
            <button onClick={onFlip}>{flipped ? "Turn back" : "Invert"}</button>
          </div>
        )
    }
    ReactDOM.render(<App />, root);
</script>

</html>

5. Final Practice

시간 변환기 & KM to Mile 변환기

<!DOCTYPE html>
<html lang="en">

<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
    function MinutesToHours()
    {
        const [amount, setAmount] = React.useState(0);
        const [flipped, setFlipped] = React.useState(false);

        const onChange = (event) => {
            setAmount(event.target.value);
        };
        const reset = () => setAmount(0);
        const onFlip = () => {
            setFlipped((current) => !current);
            reset();
        }  
        return (
          <div> 
            <div>
                <label htmlFor = "minutes" >Minutes: </label>
                <input 
                   value={flipped ? amount*60 : amount} 
                   id = "minutes" 
                   placeholder = "Minutes" 
                   type = "number"
                   onChange={onChange}
                   disabled={flipped}
                />
            </div>
            <div>
                <label htmlFor = "hours">Hours: </label>
                <input 
                   value={flipped ? amount: amount/60} //Flipped 상태라면 단위변환 보여주지 말라는 뜻 
                   id = "hours" 
                   placeholder = "Hours" 
                   type = "number"
                   disabled={!flipped}
                   onChange={onChange}
                />
            </div>
            <button onClick={reset}>Reset</button>
            <button onClick={onFlip}>{flipped ? "Turn back" : "Invert"}</button>
          </div>
        )
    }
   
    function KmToMiles() {
        const [amount, setAmount] = React.useState(0);
        const [flipped, setFlipped] = React.useState(false);

        const onChange = (event) => {
            setAmount(event.target.value);
        };
        const reset = () => setAmount(0);
        const onFlip = () => {
            setFlipped((current) => !current);
            reset();
        }  
        return (
          <div> 
            <div>
                <label htmlFor = "kilometers" >Kilometers: </label>
                <input 
                   value={flipped ? amount/0.6213 : amount} 
                   id = "kilometers" 
                   placeholder = "kilometers" 
                   type = "number"
                   onChange={onChange}
                   disabled={flipped}
                />
            </div>
            <div>
                <label htmlFor = "miles">Miles: </label>
                <input 
                   value={flipped ? amount: amount*0.6213} //Flipped 상태라면 단위변환 보여주지 말라는 뜻 
                   id = "miles" 
                   placeholder = "Miles" 
                   type = "number"
                   disabled={!flipped}
                   onChange={onChange}
                />
            </div>
            <button onClick={reset}>Reset</button>
            <button onClick={onFlip}>{flipped ? "Turn back" : "Invert"}</button>
          </div>
        )
    }
    function App() {
        const [index, setIndex] = React.useState("0") //데이터(index)가 함수(setIndex)에 의해서 수정되면 React가 UI를 새로고침해줄 것임. 
        const onSelect = (event) => {
            setIndex(event.target.value);
        }

        return (
          <div> 
            <h1>Super Converter</h1>
            <select value={index} onChange={onSelect}>
                <option value = "0">Minutes & Hours</option>
                <option value = "1">Kilometers & Miles</option>
            </select>
            {index === "0" ? <MinutesToHours /> : null}
            {index === "1" ? <KmToMiles /> : null}
          </div>
        );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
</script>

</html>

profile
배움이 즐거운 개발자

0개의 댓글