React(생활코딩)_19일차_ReactRedux(1)_Redux없는React컴포넌트구조만들기

Lina Hongbi Ko·2023년 10월 11일
0

React_생활코딩

목록 보기
20/23

저번시간에 리액트에 Ajax을 이용해 '로딩중' 표시 기능 구현을 해보았다.

요번에는 드디어 마지막 part!!!

React Redux를 들어가려고 한다.

그 전에 Redux에 대해 무지 했던 나로서,, Redux에 대한 개념 정리와 실습을 해보고, 그 다음 React Redux에 대해 공부하려 한다. ( + 생코님책과 여러 사이트들을 보며)

일단, 책에서는 Redux 없이 우리가 계속 사용했던 방식으로 컴포넌트들을 만들어서 Redux의 필요성을 느낄 수 있는 실습을 하도록 하였다.

시작해보자 :)

✏️ Redux 없는 React 컴포넌트 구조 만들기

리덕스 없이 리액트만으로 간단한 어플리케이션을 만들기.

1. 컴포넌트 생성

가장 먼저,
create-react-app을 실행시키자.

npx create-react-app react_redux

디렉토리를 생성했으면 App.js 파일로 들어가 원하는 컴포넌트들을 만들어 보도록 하자.
어플리케이션은 값을 입력하고 버튼을 누르는 부분인 AddNumber 컴포넌트와 눌렀을때 화면에 표시되는 부분인 DisplayNumber 컴포넌트를 넣어 구현할 것이다. 그리고 각 컴포넌트는 Root 컴포넌트의 하위 컴포넌트로 들어가게 할 예정이다.

// App.js 파일


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

class AddNumber extends Component {
	render(){
    	return(
        	<div>
            	<h1>Add Number</h1>
                <input type="button" value="+"></input>
                <input type="text" value="0"></input>
            </div>
        );
    }
}

class AddNumberRoot extends Component {
	render(){
    	return(
        	<div>
            	<h1>Add Number Root</h1>
                <AddNumber></AddNumber>
            </div>
        );
    }
}

class DisplayNumber extends Component {
	render(){
    	return(
        	<div>
            	<h1>Display Number</h1>
                <input type="text" value="0" readOnly></input>
            </div>
        );
    }
}

class DisplayNumberRoot extends Component{
	render(){
    	return(
        	<div>
            	<h1>Display Number Root</h1>
                <DisplayNumber></DisplayNumber>
            </div>
        );
    }
}

function App() {
	return(
    	<div className="App">
        	<h1>Root</h1>
            <AddNumberRoot></AddNumberRoot>
            <DisplayNumberRoot></DisplayNumberRoot>
        </div>
    );
}

export default App;

그리고 컴포넌트가 구분되어 보이도록 App.css파일의 내용을 아래처럼 작성해준다.

// App.css 파일

div {
	border: 5px solid #764abc;
    margin: 10px;
    color: #764abc;
    padding: 10px;
}

이렇게 저장하고 화면을 보면,

요런 결과를 확인할 수 있다.

어플리케이션 Root가 최상위에 있고, 그 아래에 AddNumberRoot와 DisplayNumberRoot, 그리고 각각의 컴포넌트 안에 실제 작업을 실행하거나 보여주는 컴포넌트인 AddNumber과 DisplayNumber 컴포넌트가 있다.

이제 파일들을 components라는 폴더를 만들어서 따로 분리하자.

// src / components / AddNumber.js 파일

import React, { Component } from 'react';

export default class AddNumber extends Component {
	render(){
    	return(
        	<div>
            	<h1>Add Number</h1>
                <input type="button" value="+"></input>
                <input type="text" value="0"></input>
            </div>
        );
    }
}

export default AddNumber;
// src / components / AddNumberRoot.js 파일

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

export default class AddNumberRoot extends Component {
	render(){
    	return(
        	<div>
            	<h1>Add Number Root</h1>
                <AddNumber></AddNumber>
            </div>
        );
    }
}

export default AddNumberRoot;
// src / components / DisplayNumber.js 파일

import React, { Component } from 'react';

export default class DisplayNumber extends Component {
	render(){
    	return(
        	<div>
            	<h1>Display Number</h1>
                <input type="text" value="0" readOnly></input>
            </div>
        );
    }
}

export default DisplayNumber;
// src / components / DisplayNumberRoot.js 파일

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

export default class DisplayNumberRoot extends Component {
	render(){
    	return(
        	<div>
            	<h1>Display Number Root</h1>
                <DisplayNumber></DisplayNumber>
            </div>
        );
    }
}

export default DisplayNumberRoot;
// App.js 파일

import React, { Component } from 'react';
import './App.css';
import AddNumberRoot from './components/AddNumberRoot';
import DisplayNumberRoot from './components/DisplayNumberRoot';

function App() {
	return(
    	<div className="App">
        	<h1>Root</h1>
            <AddNumberRoot></AddNumberRoot>
            <DisplayNumberRoot></DisplayNumberRoot>
        </div>
    );
}

export default App;

이렇게 파일을 분리하고 컴포넌트를 만들었다.

2. Redux 없이 컴포넌트의 상태 연결하기

우선 App 컴포넌트를 클래스 방식으로 변경하고, state를 추가해 number에 초깃값 0을 설정한다. 그리고 이 state값을 DisplayNumberRoot로 전달하기 위해 props를 사용했다.

// App.js 파일

import React, { Component } from 'react';
import './App,css';
import AddNumberRoot from './components/AddNumberRoot';
import DisplayNumberRoot from './components/DisplayNumberRoot';

class App extends Component {
	state = {number: 10}
	render() {
    	return(
        	<div className="App">
            	<h1>Root</h1>
                <AddNumberRoot></AddNumberRoot>
                <DisplayNumberRoot number={this.state.number}></DisplayNumberRoot>
            </div>
        );
    }
}

export default App;

이제 DisplayNumberRoot 컴포넌트에서 이 props 값을 받아 DisplayNumber 컴포넌트로 전달하는 코드를 작성해보자.

// DisplayNumberRoot.js 파일

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

export default class DisplayNumberRoot extends Component {
	render() {
    	return(
        	<div>
            	<h1>Display Number Root</h1>
                <DisplayNumber number={this.props.number}></DisplayNumber>
            </div>
        );
    }
}

App으로부터 전달받은 props값을 자식 컴포넌트인 DisplayNumber 컴포넌트에 전달한다. 이제 다시 이 값을 받아 출력하는 DisplayNumber 컴포넌트를 구현해보자.

// DisplayNumber.js 파일

import React, { Component } from 'react';

export default class DisplayNumber extends Component {
	render(){
    	return(
        	<div>
            	<h1>Display Number</h1>
                <input type="text" vlaue={this.props.number}></input>
            </div>
        );
    }
}

이렇게 하고 결과를 확인해보자.

DisplayNumberRoot의 props값으로 전달했던 10이라는 값이 잘 출력되는 것을 확인할 수 있다.

그 다음으로,

AddNumber 컴포넌트의 [+]버튼을 누르면 입력된 값이 전달되어 이 값이 다시 DisplayNumber로 전달도록 구현해보자.

// AddNumber.js 파일

import React, { Component } from 'react';

export default class AddNumber extends Component {
	state = {size:1}
    render(){
    	return(
        	<div>
            	<h1>Add Number</h1>
                <input type="button" value="+" onClick={function(){
                	this.props.onClick(this.state.size);
                }.bind(this)}></input>
                <input type="text" value={this.state.size} onChange={function(e){
                	this.setState({size:Number(e.target.value)});
                }.bind(this)}></input>
            </div>
        );
    }
}

AddNumber 컴포넌트에 state을 추가해 size라는 속성값에 초깃값을 1로 설정했다. 그리고 텍스트 입력상자에 출력되어 보이도록 했고, 이 값이 변경될때 state의 size값이 변경될 수 있게 onChange를 구현했다. 전달된 값은 문자열이므로 Number() API로 숫자로 변경되도록 하였고 setSate() 메소드로 state 값을 변경되게 하였다.

그리고 [+]버튼을 누르면 size값이 상위 컴포넌트로 전달될 수 있도록 onClick를 구현했다. props로 전달받은 onClick이벤트의 인자에 state의 size값을 전달한다.

다음으로, onClick 이벤트를 부모 컴포넌트인 AddNumberRoot에서 받아야 한다.

// AddNumberRoot.js 파일

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

exrpot default class AddNumberRoot extends Component {
	render(){
    	return(
        	<div>
            	<h1>Add Number Root</h1>
                <AddNumber onClick={function(size){
                	this.props.onClick(size);
                }.bind(this)}><AddNumber>
            </div>
        );
    }
}

export default AddNumberRoot;

AddNumber의 props로 인자가 size인 함수를 전달한다. 이 함수는 컴포넌트의 [+]버튼을 클릭했을때 AddNumber의 state.size값을 인자로 호출한다. 그리고 이 size 값을 다시 상위 컴포넌트로 전달해야하므로 또 onClick 이벤트 props를 호출해 size 값을 전달해야 한다.

// App.js 파일

import React, { Component } from 'react';
import AddNumberRoot from './components/AddNumberRoot';
import DisplayNumberRoot from './components/DisplayNumberRoot';

class App extends Component {
	state={
    	number: 10
    }
    render(){
    	return(
        	<div className="App">
            	<h1>Root</h1>
                <AddNumberRoot onClick={function(size){
                	this.setState({number:this.state.number + size});
                }.bind(this)}></AddNumberRoot>
                <DisplayNumberRoot number={this.state.number}></DisplayNumberRoot>
            </div>
        );
    }
}

export default App;

App 컴포넌트에서는 AppNumberRoot 컴포넌트의 onClick props에 size 값을 인자로 하는 함수를 전달한다. 그리고 인자로 전달된 size 값을 App 컴포넌트의 state.number값에 더한다.

이렇게 state.number 값이 변경되면 이 변경사항이 DisplayNumberRoot -> DisplayNumber로 내려가 반영된다.

코드를 저장하고, 숫자값을 입력한후 [+]버튼을 입력하면 숫자가 변경되는 것을 확인 할 수 있다.

어휴,,,
컴포넌트들이 깊이가 있는 경우 이렇게 변경사항을 최상위 컴포넌트로 전달해야하고 다시 또 하위 컴포넌트에도 전달해야 하는 아주 힘든 작업을 해보았다..

정말 생코님의 말대로 이번 실습을 통해 리덕스 없이 리액트만으로 컴포넌트들을 만들어 상태를 변경시켜주니까 넘넘 힘들다 ㅠㅠ..

그리고 게다가, 이건 아주 작은 규모의 어플리케이션인데 대규모의 작업을 하다보면 렌더링이 계속 되어서 성능에도 좋지 않을 것이다.

일전에 배운 shouldComponentUpdate 메소드를 이용해도 되지만, 매번 쓰는 것도 무리..

그래서 리덕스를 배워서 빨리 이 괴로움에서 벗어나 보자!!!


출처
생활코딩! 리액트 프로그래밍 책

profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글