// module A
export const singleton = { user: 'a', asd: 'b' }
setTimeout(() => console.log(singleton.user), 5000) // 'asd'
// module B
import { singleton } from './A'
singleton.user = 'asd'
ES module is evaluated only once on first import, this efficiently makes module exports singletons.
When a module is loaded, it is cached. So, when someone else loads it again, no new code is run. The previous exports are just returned.
인스턴스를 여러개 만들고 싶으면 class constructor 를 이용하면된다!
export class A {
constructor() {
this.user = 'asd';
this.asd = 'b';
}
}
호출 형태가 다를때 보장하지 못한다 ( 이는 또 버전 따라 다르게 반응할 수도 있다)
For example,
require(‘./foo’)
andrequire(‘./FOO’)
return two different objects, irrespective of whether or not ./foo and ./FOO are the same file
Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee that
require(‘foo’)
will always return the exact same object, if it would resolve to different files.
함수가 useState같은 외부 state 값을 의존적으로 가져다 사용해야되거나 외부 state 값을 변화시키는 때 내부 선언이 필요하다 (대부분의 컴포넌트 내부의 state를 이용하는 이벤트 핸들링 함수)
→ 컴포넌트 내부에 함수를 둬서 가두고 이용 필요
이때 컴포넌트 리렌더를 할 경우 매번 새로 함수를 생성되게 되는데 이를 방지하고자 메모이제이션 하기위해 useCallback
을 쓴다
→ 함수를 외부에 두고 import 해도 하나의 스태틱 생성만 하게 되므로 컴포넌트 리렌더의 경우에도 재생성을 하지는 않는다.
반면, 외부 상태 값에 따라 함수가 재생성 되야된다 거나 함수가 외부 상태 값을 변조시킨다 등의 경우 처럼 컴포넌트에 대한 의존성을 가지기는 어렵다
또, 특히 파라미터를 전달해서 jsx 내부의 이벤트 핸들링 함수로 이용하려 한다면 결국 jsx 안에서 콜백함수로 재선언을 해줘야한다
import React, { useState, useMemo, useCallback } from 'react';
const getAverage = numbers => {
console.log('평균값 계산중..');
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
// onChange와 onInsert 모두 Average라는 컴포넌트안의 state에 의존적
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링 될 때만 함수 생성
const onInsert = useCallback(
e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
},
[number, list]
); // number 혹은 list 가 바뀌었을 때만 재호출시 함수 재선언
const avg = useMemo(() => getAverage(list), [list]);
// 이벤트 핸들링 함수로 전달하고 리렌더시 재생성을 피하려면 결국 메모이제이션을 해야한다
// 재선언 막고 싶어서 외부함수로 호출해서 파라미터로 전달한다 하더라도 안에서 콜백 재선언 해줘야 하기 때문에
// import 해오는 의미가 없네
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;