-
[React.js] Components Interact, Import/ExportFront-End(Web)/React - 프레임워크(React, Next) 2020. 11. 26. 00:28반응형
🤷 Component(컴포넌트)의 상호작용이란?
React App은 수많은 컴포넌트들로 구성되어 있으며, 각각이 담당하는 정보의 display가 있다.
React가 유행하는 이유는 단순히 UI를 컴포넌트로 구분해서가 아닌, 그들의 상호작용에 기인했음을 알고 시작했다.
📒 Component Interact
클래스형 컴포넌트의 render() 함수는 JSX뿐만 아니라, 다른 컴포넌트도 반환할 수 있다.
class OMG extends React.Component { // JSX(<h1>) return render() { return <h1>Whooaa!</h1>; } } class Crazy extends React.Component { // Component(OMG) return render() { return <OMG />; } }
이렇듯 컴포넌트는 서로를 입출력할 수 있으며, 성질/용도에 따라 나눠진 모듈(JS파일)들 간 주고받는 동작이 이뤄진다.
📒 import & export
React 메소드 사용뿐만 아니라, 모듈간의 컴포넌트를 말 그대로 수입/수출하기 위해 사용되는 구문이다.
* ProfilePage.js (import)
import React from 'react'; import ReactDOM from 'react-dom'; import { NavBar } from './NavBar'; // * import NavBar from NavBar.js class ProfilePage extends React.Component { render() { return ( <div> <NavBar /> <h1>All About Me!</h1> <p>I like movies and blah blah blah blah blah</p> <img src="https://content.codecademy.com/courses/React/react_photo-monkeyselfie.jpg" /> </div> ); } } ReactDOM.render( <ProfilePage />, document.getElementById('app') )
* NavBar.js (export)
import React from 'react'; export class NavBar extends React.Component { // * export to other JS render() { const pages = ['home', 'blog', 'pics', 'bio', 'art', 'shop', 'about', 'contact']; const navLinks = pages.map(page => { return ( <a href={'/' + page}> {page} </a> ) }); return <nav>{navLinks}</nav>; } }
- export 문법
내보내고자 하는 메소드(변수, 클래스) 등 앞에 붙여도 되고, 메소드를 선언한 뒤 export 처리해도 된다.
// (1) 메소드 앞에 export 붙이는 경우 export const MODULES_BECAME_STANDARD_YEAR = 2015; export class User { constructor(name) { this.name = name; } } // (2) 메소드 선언 후 export 처리 function sayHi(user) { alert(`Hello, ${user}!`); } function sayBye(user) { alert(`Bye, ${user}!`); } export {sayHi, sayBye}; // 두 함수를 내보냄
- import 문법
가져오고자 하는 메소드 명을 직접 사용해도 되고, 객체 형태로 가져와서 사용해도 된다.
// (1) say.js 내 필요한 메소드 명으로 가져옴 import {sayHi, sayBye} from './say.js'; sayHi('John'); // Hello, John! sayBye('John'); // Bye, John! // (2) say.js 자체를 say(객체) 가져와서 사용 import * as say from './say.js'; say.sayHi('John'); say.sayBye('John');
두 번째 방법은 import 코드가 짧아지고 효율적이나, 첫 번째 방법처럼 구체적으로 명시하는걸 권장한다.
- 웹팩(webpack)과 같은 모던 빌드 툴은 로딩속도를 높이기 위해 모듈들을 모으는 번들링과 최적화를 수행한다. 이러한 '가지치기(tree-shaking)' 과정이 길어질 수가 있음.
- 실제 코드를 작성하는 부분에선 첫 번째 방법이 간결함. sayHi() > say.sayHi()
- 어떤 JS파일에서 어느 메소드가 사용되는지 명확하기 때문에 코드구조 파악 및 유지보수에 유리함.
- import & export 심화문법
1) .js 생략
import 시 from 'string' 부분에 '.' 이나 '/' 등이 포함되어 있으면 파일경로로 인식되어 .js를 붙일 필요가 없다.
import User from './user.js'; // shorter import User from './user';
2) as 구문
컴포넌트를 import/export 할 때, 이름을 간결하게 바꾸고자 할 때 사용되는 구문이다.
// import 'as' import {sayHi as hi, sayBye as bye} from './say.js'; hi('John'); // Hello, John! bye('John'); // Bye, John! // export 'as' // 📁 say.js export {sayHi as hi, sayBye as bye}; // 📁 main.js import * as say from './say.js'; say.hi('John'); // Hello, John! say.bye('John'); // Bye, John!
3) export default 구문
모듈은 복수의 메소드를 포함한 모듈 / 한 개의 메소드만 선언된 모듈들 두 가지 경우로 나뉘며 후자를 선호한다.
파일 개수가 많아지기 때문에, 모듈에서 하나의 메소드를 제공하는 것을 명시하는 export default 구문이 존재한다.
// 📁 user.js export default class User { // export 옆에 'default'를 추가 constructor(name) { this.name = name; } } // 📁 main.js import User from './user.js'; // {User}가 아닌 User로 클래스 가져옴 new User('John');
default는 메소드 선언 후 export 시, 아래와 같이 지정할 수 있다.
function sayHi(user) { alert(`Hello, ${user}!`); } // 함수 선언부 앞에 'export default'를 붙여준 것과 동일 export {sayHi as default};
돌아가서, 처음 코드처럼 default 메소드가 존재하는 경우 import 시 {}를 사용할 필요가 없다.
named export default export export class User {...} export default class User {...} import {User} from ... import User from ... named와 default 동시에 사용하는 모듈도 문제는 없지만 자주 통용되는 방법은 아니다. (named는 이름 없으면 에러!)
만약 둘 다 존재하는 모듈이 있다면 아래와 같이 가져올 수 있다.
* export part
// 📁 user.js export default class User { // default export constructor(name) { this.name = name; } } export function sayHi(user) { // named export alert(`Hello, ${user}!`); }
* import part
// (1) named 가져올 때 처럼 중괄호({}) 활용 import {default as User, sayHi} from './user.js'; new User('John'); // (2) *로 모듈 내 모든 메소드 가져오기(defalut = User) // 📁 main.js import * as user from './user.js'; let User = user.default; // default export new User('John');
첫 번째 경우처럼 default는 이름을 지정할 수 있지만, 통상 모듈명(파일명)으로 지정하는 것이 암묵적인 규칙이다.
4) 모듈 다시 내보내기 (export {컴포넌트} from '경로')
export - from 문법을 통해, 컴포넌트를 가져옴과 동시에 내보낼 수 있다.
NPM을 통해 외부에 공개할 '패키지(package)'를 만들고 있다고 가정하자. 여기에는 수많은 모듈이 포함되어 있을거고, d일부는 외부에 표현되는 기능, 일부는 이를 도와주는 헬퍼를 담당하고 있다.
auth/ index.js user.js helpers.js tests/ login.js providers/ github.js facebook.js ...
이와 같은 패키지라고 하면, 진입점 역할인 index.js를 통해 외부 개발자들은 필요한 컴포넌트를 가져갈 것이다.
import {login, logout} from 'auth/index.js'
이 때, 패키지 내부를 외부 개발자가 건드리지 못하도록 필요기능을 index.js에 실어서 바로 내보낼 때 사용된다.
// 📁 auth/index.js export {login, logout} from './helpers.js'; //import {login, logout} from './helpers.js'; //export {login, logout}; export {default as User} from './user.js'; //import User from './user.js'; //export {User};
아래가 default를 다시 내보낸 경우인데, User 클래스명이 아닌 {default as User} 혹은 {default} 로 내보내야 한다.
또한, *로 내보낼 경우 named export만 처리되므로, 반드시 아래와 같이 named와 default 각각 내보내야 한다.
export * from './user.js'; // named export를 다시 내보내기 export {default} from './user.js'; // default export를 다시 내보내기
Codecademy로 튜토리얼 진행하면서, 상호작용 전체(import/export + props, state)를 한번에 적으려했으나 많았다...
대신 단순하다고 생각한 import/export의 심화적인 알고리즘도 공부하는 좋은 기회였다.
특히, import 시 중괄호({}) 사용유무의 이유에 대해 정확히 알게 된 좋은 계기였다.
import/export 부분은 아래 사이트를 많이 참고 및 차용하였다.
ko.javascript.info/import-export (출처: JAVASCRIPT.INFO 전문)
반응형'Front-End(Web) > React - 프레임워크(React, Next)' 카테고리의 다른 글
[React.js] Lifecycle (0) 2020.11.27 [React.js] State (0) 2020.11.26 [React.js] Props (0) 2020.11.26 [React.js] Component 기본 (0) 2020.11.24 [React.js] JSX(Syntax extension for JS) (0) 2020.11.23