์๋ ํ์ธ์ @ericanderson
์ค์ ๋ก ์ฌ์ฉํ ๋ ์ด ๋ณ๊ฒฝ ์ฌํญ ์ ๋ง์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
props ๋๋ state์ ์์ฑ์์ ์ ์๋ก ์ด๋์ ๋๋ฅด๋ฉด Typescript๊ฐ ์ด๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
interface MyComponentProps {
name: string;
}
export abstract class MyComponent extends React.Component<MyComponentProps , void> {
myMethood() {
this.props.name; //<-- Go To definition in name
}
}
๋ฉค๋ฒ๊ฐ ํฉ์ฑ์ ์ผ๋ก ์์ฑ๋์๊ธฐ ๋๋ฌธ์ ์ดํด๊ฐ ๋์ง๋ง ์ด์จ๋ ์ง์ฆ๋ฉ๋๋ค.
๋ ์ค์ํ ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ด ์ถ์ ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ์ ๋๋ค.
interface MyBaseProps {
onChange?: (val: any) => void;
}
export abstract class MyBase<P extends MyBaseProps> extends React.Component<P, void> {
myMethood() {
this.props.onChange!(2); //The type is S["onChange"] instead of (val: any) => void and so is not invocable.
}
}
TS๋ onChange ์์ฑ์ด ์์์ ๋ณด์ฌ์ค ์ ์์ง๋ง ๋๋๋ก ๊ทธ์ ์ ํ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
if ๊ฐ ๊ณตํต ์ํ๊ณผ ๊ธฐ๋ฅ์ ๊ณต์ ํ๋ ๊ตฌ์ฑ ์์์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๊ฐ์ฅ ์ค์ํ ๋ณ๊ฒฝ ์ฌํญ ์ ๋๋ค. TS ์ปดํ์ผ๋ฌ์ ๋ฌธ์ ์ฒ๋ผ ๋ณด์ด์ง๋ง ์์ ๋ ๋๊น์ง์ ๋๋ค.
์ด ๋ณ๊ฒฝ์ด React์ ๊ธฐ๋ฅ์ ์๋๋ฅผ ์ ํฌ์ฐฉํ๋ค๋ ์ ์๋ ๋์ํ์ง๋ง ์์ฑ์์์์ ๊ฐ์ด ๋ช ๋ น์ ์ผ๋ก ์ํ๋ฅผ ์์ ํ ์ ์๊ณ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ณ forceUpdate๋ฅผ ํธ์ถํ๋ฉด ๋ชจ๋ ๊ฒ์ด ์ ์์ ์ผ๋ก ์๋ํ๋ ์ ํจํ ์ํฉ์ด ์์ต๋๋ค.
C#
this.state.name = "John";
this.forceUpdate(); //Ok as long as you don't setState afterwards, but calling setState also is annoying with the callback.
์ถ์ฒ์ธ๊ฐ์? ์๋์.
๊ธ์ง๋์ด ์์ต๋๊น? ๋ํ ๊ทธ๋ ์ง ์์ผ๋ฉด forceUpdate๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.
๋ฌผ๋ก ์ํ๋ฅผ S
(๋๋ any
)๋ก ๋ณํํ๊ณ ๋ณ๊ฒฝํ ์ ์์ง๋ง ์ผ๋ฐ์ ์ธ ํจํด์ธ ๊ฒฝ์ฐ ๋ฒ๊ฑฐ๋กญ์ต๋๋ค.
TS์ ์๋ก์ด ๋ฐ์ง๊ฑฐ๋ฆฌ๋ ๊ธฐ๋ฅ์ด ์ด ๊ฒฝ์ฐ ์๋ฃจ์ ๋ณด๋ค ๋ ๋ง์ ๋ฌธ์ ๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ํ๊น์ง๋ง ์์งํ ์ฌ๊ธฐ๋ ๋ง์ฐฌ๊ฐ์ง๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋ฐ๋ฉด setState
์ ๋ณํ๋ ๋๋จํฉ๋๋ค ๐ , Pick<S,K>
์ ๋ํด ๋ชฐ๋์ต๋๋ค.
Visual Studio๋ ์ด๋ค ๋ฒ์ ์ typescript๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๊น?
@vsaio for sa
๋ฌธ์ 1์ ๊ฒฝ์ฐ TS 2.1.5 ๋ฐ ์ต์ VSCode๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๋ฐฉ๋ฒ์ด ์ ์๋ํฉ๋๋ค. ๋๋ windows/VS๊ฐ ์์ด์ ๊ฑฐ๊ธฐ์์ ํ์ธํ ์ ์์ง๋ง ํ๋ฌ๊ทธ์ธ์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์๊ฑฐ๋ TS 2.1.5์ ์์ง ์์ ๊ฒ์ ๋๋ค.
๋ฌธ์ 2์ ๋์ผ
VS 2015(TS 2.1.5.0 ํฌํจ)
๋ฌธ์ 3์ ๋ ผ์์ ์ฌ์ง๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
React์์ ์์ ์๋ฅผ _๊ธฐ์ ์ ์ผ๋ก_ ํ ์ ์๋ค๋ ๊ฒ์ ์ณ์ง๋ง, ๋๋ ๊ทธ๊ฒ์ด React๊ฐ ์ฌ์ฉ๋๋๋ก ์๋๋ ๋ฐฉ์์ด ์๋๋ผ๊ณ ํ์คํ ์ฃผ์ฅํ๊ณ ์ถ์ต๋๋ค.
์ด๊ฒ์ 3๊ฐ์ง ๋ณ๊ฐ์ ๊ฒฝ์ฐ๋ก ๋๋ ์ ์์ต๋๋ค.
interface State {
bar: number;
}
interface Props {
baz: number;
}
class Foo extends React.Component<Props, State> {
public state: State = {
bar: 5,
};
}
interface State {
bar: number;
}
interface Props {
baz: number;
}
class Foo extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
bar: props.baz,
};
// or
this.setState({
bar: props.baz,
});
}
}
forceUpdate
๋ก ๋ฌด์์ ํ ๋น์ฌ๋๋ค์ "์ฌ๋ฐ๋ฅธ" ๋ฐฉํฅ์ผ๋ก ๋ฐ์ด๋ถ์ด๋ ๊ฒ์ด ๋ ๋ซ๋ค๊ณ ์๊ฐํ๋ฉด public state
๋ฅผ ๋ค์ ์ ์ธํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.
interface State {
bar: number;
}
class Foo extends React.Component<{}, State> {
public state: State;
public myMethod() {
this.state.bar = 5;
}
}
๋ด ๋ฌธ์ ๋ ์ ๋ค๋ฆญ ๋ถ์ฐ์ ์์ต๋๋ค. ํนํ ์ผ๋ฐ์ ์ผ๋ก ์ ๋ ฅ๋๋ ํด๋์ค ๋ด์์ ์ ๋ ฅํ๊ธฐ ์ํ ๊ฒ์ ๋๋ค. ์๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ณณ์ ์์ฃผ ์ต์ํ์ ์ํ์ ๋๋ค.
class TBaseState {
public value: string;
}
function globalFunc<T extends Readonly<TBaseState>>(item: T) {
}
class MyComponent<TProps, TState extends TBaseState> extends React.Component<TProps, TState> {
broken() {
// typing of this.state is Readonly<TState>
// this is not assignable to Readonly<TBase>
globalFunc(this.state);
// this is a horrible hack to fix the generics variance issue
globalFunc(this.state as TState as Readonly<TBaseState>);
}
}
class MyState extends TBaseState {
}
let component: MyComponent<any, MyState>;
// here the typing of component.state is Readonly<MyState>
// this is assignable to Readonly<TBase>
globalFunc(component.state);
๋๋ TS 2.1.5.0์์๋ค
๊ทธ๋ฌ๋ VS์์ VS ์ฝ๋๋ณด๋ค ์ต์ ์ TS ๊ฒฝํ์ด ์์ ์ ์์ต๋๋ค...
๋ฌธ์ 1์ ๊ฒฝ์ฐ ์ ์๋ก ์ด๋ TS๋ VS ์ฝ๋์์๋ ์๋ํ์ง ์์ต๋๋ค.
interface MyComponentProps {
name: string;
}
export abstract class MyComponent extends React.Component<MyComponentProps , void> {
fullName: string;
myMethood() {
this.props.name; //<-- doesnt work
this.fullName; //<-- works
}
}
๋ฌธ์ 2์ ๊ฒฝ์ฐ VS Code๊ฐ ๋ ์ ์๋ํ๋ค๋ ๊ฒ์ ์ฌ์ค์ ๋๋ค.
VS๊ฐ ํผ๋์ค๋ฌ์ ๋ณด์ด๋ ๋์:
VSCode ๋ฐ ๋ฌธ์ 1์ ๊ฒฝ์ฐ ๋ ๋๋ํ ์ฒ๋ฆฌ๊ฐ ํ์ํ "์ต์ Typescript ๋ฐ Javascript ๋ฌธ๋ฒ"์ฉ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@patsissons ํฅ๋ฏธ๋ก์ด ์์ง๋ง ์ ์ ํ์ผ์ ๋ฒ๊ทธ๋ณด๋ค typescript์ ๋ฒ๊ทธ๋ฅผ ๋ ์ ๋ํํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด, setState
๋ S
๋ฅผ ์ทจํ๋ ๋ฐ ์ฌ์ฉ๋์์ต๋๋ค. ์ด๋ ์ฐ๋ฆฌ๊ฐ setState({foo:5} as any as State)
์ ๊ฐ์ ์ด์ํ ํธ๋ฆญ์ ์ํํ๊ฑฐ๋ ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ฌ์ฉํด์ผ ํ๋ ๋ถ๋ถ์ ์ํํ๋ ๊ฒ์ ์๋ฏธํ์ต๋๋ค. ์ปดํ์ผ๋ฌ์ ํํ๋ ฅ ๋ถ์กฑ์ผ๋ก ์ธํด ์
๋ ฅ์ด "์๋ชป"๋๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋๋ ์ด๊ฒ์ด ์ด ๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ๋ฅผ ํ์ํ๊ธฐ ์ํด README๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋ํ ์ ์ ํ ์ฃผ์ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
TS์ ๋ฌธ์ ๋ฅผ ์ ์ถํ์ จ์ต๋๊น?
๋ฐ๋ผ์ ์ด ๋ณ๊ฒฝ ์ฌํญ์ ์์ฆ ๋ชจ๋ VS๋ฅผ ์ค๋จํ๊ณ ํ๋ฌ๊ทธ์ธ์ด ์๋ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ ๋ชจ๋ VS ์ฝ๋์์ ์ ์๋ก ์ด๋์ ๋นํ์ฑํํฉ๋๋ค...
๋ํ ์์ ์ฑ ์ฃผ์ฅ์ด ์์ต๋๋ค. ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์๋๋ API๊ฐ ์์ญ์ต ๊ฐ ์์ผ๋ฉฐ ์์ฆ์๋ ๊ทธ๋ ์ง ์์ต๋๋ค. ๋จ์ง React.d.ts์๋ง ์์ต๋๋ค.
interface ComponentLifecycle<P, S> {
componentWillMount?(): void;
componentDidMount?(): void;
componentWillReceiveProps?(nextProps: Readonly<P>, nextContext: any): void;
shouldComponentUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: Readonly<any>): boolean;
componentWillUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: Readonly<any>): void;
componentDidUpdate?(prevProps: Readonly<P>, prevState: Readonly<S>, prevContext: Readonly<any>): void;
componentWillUnmount?(): void;
}
์๋ฅผ ๋ค์ด ์ด๋ฒคํธ ๊ฐ์ฒด์ ๊ฐ์ด ์์ ๋์ง ์๋ ๊ธด ๊ผฌ๋ฆฌ๊ฐ ์๋ '๊ณ ์ ' ๋๋ 'Inmmutable.js'์ readonly๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ์ถํ์ง ์์์ต๋๋ค. ์ ๋ ์ค๋ ์๋ก์ด Readonly<T>
์ ํ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฝ๋๋ฅผ ๊ฐ์กฐํ๊ณ ์์ต๋๋ค. ์ด๊ฒ์ ์ ๋๋ก ์
๋ ฅ๋ ์๋ฃจ์
์ด ์๋ ๊ฒฝ์ฐ์์ต๋๋ค. ๊ณ์ํด์ ๋ฌธ์ ๋ฅผ ์ ๊ธฐํ์ธ์. ์ ๋ ์ค๋ ํ๋ฃจ ์ค ๋๋ถ๋ถ์ ์๊ฐ์ ์ฝ๋ ํจ์น๋ก ๋ฐ์ ๊ฒ์
๋๋ค.
์ ์, ์ ๊ฐ ๋์น ๋ถ๋ถ์ด ์๋ค๋ ๊ฒ์ ์๊ณ ์์์ต๋๋ค. @olmobrutall ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ํ์ํ๊ธฐ ์ํด ๋์ ํ ์ํ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์งํ๋ค๋ฉด ํด๋น ๋ฉ์๋๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ํ์ง๋ง ๋จผ์ ํด์ผ ํ ์ณ์ ์ผ์ ๋ํ ํฉ์๊ฐ ํ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
VS ๋ธ๋ ์ดํฌ์ ๊ดํด์๋ ๋ฌด์์ด ์ณ์์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ผ๋ถ ๋๊ตฌ๊ฐ ์ต์ ์ํ๋ก ์ ์ง๋์ง ์๊ธฐ ๋๋ฌธ์ ์ ํ์ ๋ณด๋ฅํด์ผ ํฉ๋๊น?
@patsisson ๋ชจ๋ ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ๊ธฐ ์ ์ ์ด๊ฒ์ด ์ด๋ป๊ฒ ์งํ๋๋์ง ๋ณด๊ณ ์ถ๋ค๋ฉด ์ง๊ธ ๋น์ฅ์ ๋ฐ์์ ๋ํ ์์ ๋ง์ ํ์ดํ์ ์ ๊ณตํ ์ ์์ต๋๋ค. https://ericlanderson.com/using-custom-typescript-definitions-with-ts-2-x-3121db84015d#.ftlkojwnb
์ฐ๋ฆฌ์ ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด VS๋ ํญ์ ์ฝ๊ฐ ๋ค์ณ์ ธ ์์ต๋๋ค. ์ฐ๋ฆฌ ๊ฐ๊ฒ๋ ํ์ฑ ํ์ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์ ์ํํ๊ธฐ ์ํด vscode๋ฅผ ์ฌ์ฉํ๋ฉฐ, VS๋ ๋จ์ํ ์ฝ๋ ํ์ผ์ ํจ์นํ๊ฑฐ๋ ํ์ ์คํฌ๋ฆฝํธ๊ฐ ์๋ ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ ๋ฐ ๋ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค.
@ericanderson ์ง๊ธ ์ ํดํน ์ด ๊ทธ๋ ๊ฒ ๋์์ง ์์ต๋๋ค. Readonly<Base>
T
$ ๋ฅผ ์ป์ผ๋ ค๋ฉด Readonly<T>
๋ฅผ ์ป์ด์ผ ํฉ๋๋ค.
์ฐ๋ฆฌ๋ 'react.d.ts'์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ์ด ๋จ์ผ ๋ฉค๋ฒ ์ ์ธ์ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค. VS๊ฐ ์ค๋น๋ ๋๊น์ง ๋ณด๋ฅํ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ํ ์ ์ธ๊ณ ์ ํ์ 50%๊ฐ API์์ ๊ฐ์ ธ์จ ๊ฐ์ฒด์ ๊ฐ์ด ์ฝ๊ธฐ ์ ์ฉ์ด๋ฏ๋ก ์ฃผ์์ ๋ฌ ํ์๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
Get-only ์์ฑ์ ๊ฐ๋๋ก ๋ช ์์ ์ผ๋ก ๋ณํ๋ ๊ฐ์ฒด์๋ Readonly๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋๊ฒฐ์ฒ๋ผ.
@olmobrutall Readonly
๋ ์๋ก์ด ๊ฒ์ด๋ฏ๋ก ์ ํํ ๋ชจ๋ฒ ์ฌ๋ก๊ฐ ์ค์ ๋ก ์ ์๋์ง ์์ต๋๋ค. ์ ๋ ๊ฐ์ธ์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ด Readonly<>
๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค๋ ๊ฒ์ ๋ํ๋ด๋ ๋ฐ ๋์์ด ๋๋ค๊ณ ์ ์ธํ๋ ๊ฒ์ ์ ํธํฉ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก React๋ setState
state
๋ฅผ ์์ ํ๋ ๊ฒ์ ๊ธฐ๋ํ์ง ์์ผ๋ฏ๋ก ์ด ๋ณ๊ฒฝ์ผ๋ก ์ธํด ์ฌ๊ณ ๋ก ์ธํด ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค. ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ณด๋ค TypeScript๋ฅผ ์ฌ์ฉํ๋ ์ฃผ์ ์ด์ ์ค ํ๋์
๋๋ค.
Object.freeze
์ ๋ํด ๋ธ๋ผ์ฐ์ ๊ฐ์ ์ฑ๋ฅ์ด ๋ ์ผ๊ด์ ์ด์๋ค๋ฉด React ์ฌ๋๋ค์ด setState
์ดํ์ ์ค์ ๋ก ๋ฉ์ถ๊ธฐ ์์ํ ๊ฒ์ด๋ผ๊ณ ์์ํ ์ ์์ต๋๋ค.
forceUpdate์ ๋ชฉ์ ์ ๋ฌด์์ ๋๊น?
๋๋ ๋๊ตฌ ์ ๋ฐ์ดํธ์ ๊ด๋ จํ์ฌ ํ์คํ ์ ํ์ด ์ด๋ป๊ฒ ์๋ํด์ผ ํ๋์ง์ ๋ํ ๋ค๋ฅธ ์ฌ๋๋ค์ ์๊ฐ๊ณผ ๋ฐ์์ ๋ํ ์ฝ๊ธฐ ์ ์ฉ์ ๋ํ ์ฒ ํ(๋ฐ ํน์ ๊ฐ์ฒด๋ฅผ ์์ ํ์ง ์๋๋ค๋ ์๋๋ฅผ ๊ฐ์ง ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)์ ๋ํ ๋ค๋ฅธ ์ฌ๋๋ค์ ์๊ฐ์ด ๊ถ๊ธํฉ๋๋ค.
cc/ @johnnyreilly @vsaio @pspeter3 ๋ฐ์์ ๋ํ ์๊ฐ๊ณผ ์ผ๋ฐ์ ์ธ ๋ค๋ฅธ ์๊ฐ
cc/ @andy-ms @mhegazy ๋ ํด๋ง ์
๋ฐ์ดํธ์ Readonly
์ ์ด์ฑ์ ์ธ ์ฌ์ฉ์ ์ํด ํ์คํ Typed๊ฐ ์ด๋ป๊ฒ ์ฒ ํ์ ์ผ๋ก ์งํ๋์ด์ผ ํ๋์ง์ ๋ํ ์๊ฐ์
๋๋ค.
@olmobrutall ์ฐ๋ฆฌ๋ forceUpdate
๋ฅผ ์ฌ์ฉํ์ฌ ์ํ ์ธก์ ๊ด์ฐฐ ๊ฐ๋ฅํ ์ด๋ฒคํธ์์ ๊ตฌ๋๋๋ ๋ฐ์ ์ธก์ ๋ ๋๋ฅผ ๋๊ธฐ์ด์ ๋ฃ์ต๋๋ค.
์
๋ฐ์ดํธ :
์คํด๊ฐ ์๋๋ก ์๋๋ฆฌ์ค๋ฅผ ์กฐ๊ธ ์ค๋ช
ํ๊ฒ ์ต๋๋ค. ์ํ ๊ฐ์ฒด๋ ์ค๋ ์ง์๋๋ ๋ถ๋ณ ๊ฐ์ฒด์
๋๋ค(๋ฐ๋ผ์ Readonly<T>
๋ ์ค์ ๋ก ์ฐ๋ฆฌ์๊ฒ ๋งค์ฐ ์ ํฉํฉ๋๋ค). ์ด๋ฌํ ์ํ ๊ฐ์ฒด์๋ stateChanged
๋ผ๋ ์๋ฆผ ๊ด์ฐฐ ๊ฐ๋ฅ ํญ๋ชฉ์ผ๋ก ์ ์
๋๋ ์ฌ๋ฌ rxjs
๊ด์ฐฐ ๊ฐ๋ฅ ์คํธ๋ฆผ์ด ํฌํจ๋์ด ์์ต๋๋ค. React ๊ตฌ์ฑ ์์๋ ์ด๋ฒคํธ์ ๋ํด ์ด ์ต์ ๋ฒ๋ธ์ ๊ด์ฐฐํ๊ณ ํด๋น ์ด๋ฒคํธ๋ฅผ forceUpdate
์ ๋ํ ํธ์ถ๋ก ์ ์
ํฉ๋๋ค(๋๋ฐ์ด์ฑ ํ). ์ฌ์ค์ ์ฐ๋ฆฌ์ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ๋ ์ํ ๋ด์ ์์ง๋ง ์ํ ์์ฒด์ ์ํ์ ์กด์ฌํ๋ ๋ฉค๋ฒ๋ ๋ชจ๋ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ํ์คํ React์ ํ์ค ์ฌ์ฉ ์ฌ๋ก๋ ์๋์ง๋ง ํ๋ฆ์ด ๋งค์ฐ ์ ์ฌํฉ๋๋ค. ์ฌ๋ ๋๋ง์ด ํ์ํ ๋ ๊ตฌ์ฑ ์์์ ์๋ฆฌ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๋ ์ค๋งํธ ์ํ ๊ฐ์ฒด๋ง ์์ผ๋ฉด ๋ฉ๋๋ค.
@ericanderson ์ฃผ์ ๋ฌธ์ ๋ ์ด๋ฌํ ์ ํ ์ ์๊ฐ SemVer ๋ฌธ์ ๋ก ๊ณ ํต๋ฐ๊ณ ์๋ค๋ ๊ฒ์
๋๋ค. ์ ํ ์ ์ ๋ฒ์ ์ ํด๋น ๋ชจ๋ ๋ฒ์ ์ ํฌ๊ฒ ์ฐ๊ฒฐ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ ํ ์ ์ ๋ณ๊ฒฝ์ ์ผ์ผํค๋ ๋ถ ๋ฒ์ ๋ฒํ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ @types
๋ฒ์ ์ package.json
์ ๊ณ ์ ํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ํ์ผ.
@olmobrutall ๋ฐ์ ๋ฌธ์์์:
์ผ๋ฐ์ ์ผ๋ก forceUpdate()์ ๋ชจ๋ ์ฌ์ฉ์ ํผํ๊ณ render()์ this.props ๋ฐ this.state๋ง ์ฝ์ด์ผ ํฉ๋๋ค.
๋ฐ์ ๊ฐ์ด๋๋ ์ฌ์ค ์ํ๋ฅผ ์ง์ ์ ๋ฐ์ดํธํ์ง ๋ง๋ผ๊ณ ์๋ ค์ค๋๋ค: https://facebook.github.io/react/docs/state-and-lifecycle.html#do -not-modify-state-directly
forceUpdate
๋ ๋ด๊ฐ ์ฝ์ ๋๋ก ๊ตฌ์ฑ ์์๊ฐ props ๋๋ state์ _not_ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ ๊ตฌ์ฑ ์์๋ฅผ ๊ฐ์ ๋ก ์
๋ฐ์ดํธํ๊ธฐ ์ํ ๊ฒ์
๋๋ค.
@patsisson ๋ด๊ฐ ํ๋ฆด ์๋ ์์ง๋ง SemVer๊ฐ API ๋ฐ ์๋ฏธ๋ก ์ ์๋์ ์ญํธํ๋๋๋ก ์ค๊ณ๋์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ํ์ง ์์ ๋ฐฉ์์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํด์(๋ฌธ์์ ๋ฐ๋ผ) ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ํ์ง ์์ ์ฌ์ฉ์ ๊ณ์ ์ง์ํด์ผ ํ๋ค๋ ์๋ฏธ๋ ์๋๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ์๋ SemVer ๋ด์์ ์ ํํ์ง ์์ง๋ง ์ผ๋ถ ์ฌ๋๋ค์ด ์ฌ์ฉํ๊ฒ ๋ ์๋ฏธ ์ฒด๊ณ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ฆ, Readonly<>
์์ state
๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋๋ฌด ํฐ ๋ณ๊ฒฝ์ด์ง๋ง ์ ์ ๋์ ์ฌ๋ฐ๋ฅธ ๋ณ๊ฒฝ์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. ์ธ์ ํ์คํ Typed๋ก ์ถ์๋์ด์ผ ํฉ๋๊น? state
๋ฅผ Readonly<>
๋ก ํ์ํ๋ ์
๋ฐ์ดํธ๋ฅผ ๋ฐ์ผ๋ฉด ์ฝ๋๋ฅผ ํญ์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
๋๋ ์ฌ์ ํ Readonly<>
๊ฐ state
์ ์ ์ฉ๋์ด semver, tooling ๋๋ ๋ค๋ฅธ ๊ฒ์ ๋ํด ํ ๋ก ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋๋ ๊ฒ์ด ์ณ์์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋ด ์ง๊ฐ์ ์ณ์๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ๊ฒํ ํ ์ฌ๋๋ค์ ๊ทธ๊ฒ์ ๋ฌธ์ ๋ก ์ ๊ธฐํ์ง ์์์ต๋๋ค. React ํ์ ์๋์ ์ผ์นํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋๋ ํ์คํ Typed์ ๋ํ ๋ฐ์์ ๋ํด ๋ฆฌ๋ทฐ์ด๋ค์๊ฒ ๋งก๊ธธ ์ ์์ด ๊ธฐ์ฉ๋๋ค(์์์ ๋ชจ๋ ์ฐธ์กฐํ์ต๋๋ค).
๋ฐ๋ผ์ Observable์ ๊ฐ์ ์ ๋ฐ์ดํธ ์ํ๋ฅผ ๋ณ๊ฒฝํฉ๋๊น? ๋ฐ๋ผ์ ์ํ๋ฅผ ๋ช ๋ น์ ์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ ์ด๋ ์ ๋ ํ์ฉ๋ฉ๋๋ค.
Readonly๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์์น๊ฐ 100% ์ ์๋์ง ์๋๋ค๋ ๊ฒ์ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๊ตฌ๊ฐ ์ค๋น๋๊ธฐ ์ ์ ๋ ผ๋์ ์ฌ์ง๊ฐ ๋ง๊ณ ๋ง์ด ์ฌ์ฉ๋๋ ์์ฐ์ผ๋ก ์์ํด์ผ ํฉ๋๊น?
์ ๋ ๋ชจ๋ ๊ฐ๋ ฅํ ํ์์ ์ฌ์ฉํ๊ณ strictNullChecks๊ฐ ์๋ 6๊ฐ์ ํ๋ก์ ํธ๋ฅผ ๋ชจ๋ ๊ด๋ฆฌํ์ง๋ง ์ฌ๊ธฐ์์ ์ป๋ ์ด์ ์ ํ์ฌ ์์ฑํ๋ ๋ฌธ์ ๋ณด๋ค ํจ์ฌ ์ ์ต๋๋ค.
@ericanderson ๋๋ SemVer2๊ฐ ^15.0.0
์ ๊ฐ์ ๋
ธ๋ ๋ฒ์ ์ ์ธ์ ํ์ฉํ๋๋ก ์ค๊ณ๋์์ผ๋ฉฐ ๋ชจ๋์ ๋ํ ๋ชจ๋ ๋ง์ด๋ ๋๋ ํจ์น ์
๊ทธ๋ ์ด๋(์: 15.0.1
๋๋ 15.1.0
)๊ฐ ํฌ๋ช
ํ๊ฑฐ๋ ์ ์ด๋ ์ธ๋ถ ๊ด์ ์์ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋ฉ๋๋ค. ๋ชจ๋ ์ฃผ์ ์
๊ทธ๋ ์ด๋( 16.0.0
)๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํ๊ธฐ ์ํด ๋ฒ์ ์ ์ธ์ ์กฐ์ ํด์ผ ํฉ๋๋ค. ์ด๊ฒ์ ๋ณธ์ง์ ์ผ๋ก ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ํ์ดํ ์์คํ
์ผ๋ก ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ฐจ๋จํฉ๋๋ค. ๊ทธ๋ฌ๋ ํ์ฌ ์ ํ ์ ์ ๋ฒ์ ์ ํด๋น ๋ชจ๋ ๋ฒ์ (๊ด๋ก์ ๋ฐ๋ผ)์์ ๋ฒ์ด๋ ์ ์์ผ๋ฏ๋ก ์ด๋ฌํ ๋ถ์ฐ์์ฑ์ด ๋ฐ์ํฉ๋๋ค.
์งง์ ๋ฒ์ ์ ์ ํ ์ ์๊ฐ ๋ชจ๋ ์์ฒด๋ฅผ ์ ํ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ๋์ ๋ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์ง ์ ์์ผ๋ฉฐ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์๋ ์ฃผ์ ๋ฒ์ ๋ฒํ๊ฐ ํ์ํ๋ค๋ ๊ฒ์ ๋๋ค.
ํ์ง๋ง PR์ ์ ๊ฑฐํ๋ forceUpdate๋ฅผ ๋ง๋ค์ง๋ ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ ์ฃ ?
๊ทธ๋ฐ ๋ค์ forceUpdate๊ฐ ์๋ ๊ฒฝ์ฐ ์ํ๋ฅผ ๋ฐ๋์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
์ด๋ก ์์ผ๋ก๋ ๊น์ ๋ถ๋ณ ์ํ ๊ทธ๋ํ๋ฅผ ์ฌ์ฉํด์ผ ํ์ง๋ง ๋งค์ฐ ์์ฃผ ์ํ๋ฅผ ๋ช ๋ น์ ์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ ๊ด์ฐฎ๊ณ ๋ชจ๋ ๊ฐ๋ฐ์๊ฐ ์๊ตฌ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์์ด๋์ด๋ฅผ ๋ฐ์๋ค์ด๋ ๊ฒ์ ์๋๋๋ค.
๋คํํ React๋ ์ค์ผ์ดํ ๊ฒฝ๋ก๋ฅผ ํ์ฉํ๊ณ ์ํ๋ฅผ ์ง์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. TS ๊ฐ๋ฐ์๊ฐ ํด๋น ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ธ์งํ ๊น์? ๋๋ฌด ๊ฐ๋ถ์ฅ์ ์ธ๊ฑฐ ์๋๋๊น?
์๋ฅผ ๋ค์ด Vue.js๋ ๋ช ๋ น์ ๋ณ๊ฒฝ์ ์ด์งํฉ๋๋ค. ๊ทธ๊ฒ์ด React์ ์ํฅ์ ์ค๋ค ํด๋ ๋๋ผ์ง ์์ ๊ฒ์ ๋๋ค.
๋ํ ๋๋ ์ผ๋ง ์ ์ ๋ชจ๋ Redux ํ์ฌ ์์ด React ์ฌ์ฉ์ ๊ถ์ฅํ๋ React ์์ฑ์์ ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ์ ์ฝ๊ณ ์์์ต๋๋ค(๊ธฐ์ตํ ์ ์์).
๊ทธ๋ ์ง ์์ผ๋ฉด ๋ด ์ ์ฅ์ ๊ฐ๋ฅํ ํ ๋นจ๋ฆฌ ์ ํ ์ ์๋ฅผ ๊ฒ์ํ๋ ๊ฒ์ ๋๋ค. ๋ด ์ ์ผํ ๊ด์ฌ์ฌ๋ ์๋ํ์ ๋๋ค. ์ ํ ์ ์ ๋ฒ์ ๊ด๋ฆฌ์ ํ์ฌ ์ํ๊ฐ ์ฃผ์ด์ง๋ฉด ์์ค ๋ณ๊ฒฝ ์์ด ์ฐ์ ๋น๋๊ฐ ์ค๋จ๋ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ ํ์ ๋น๊ฒฐ์ ์ CI ์คํจ๋ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ํธ์ํ ๋ค์ ๋ณ๊ฒฝ ์ฌํญ์ด ๋น๋ ์ค๋จ๊ณผ ๊ด๋ จ์ด ์์์ ์๊ธฐ ๋๋ฌธ์ ์๋ฌด๋ ๋น๋ ์ค๋จ์ ๋ณด๊ณ ์ถ์ดํ์ง ์์ต๋๋ค.
์๊ณ ๋์ ๊ฐ์ธ์ ์ธ ์๊ฒฌ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์์ ์๊ฐ๊ณผ ๋นํ์ค React ์ฑ์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊ฐ์ํ ๋ Readonly๊ฐ ์ณ๊ณ ์์ ์ฑ์ ์ํด ํ์ํ ์ ์ผํ ๋ณ๊ฒฝ์ ์ผ์นํ๋๋ก ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ฒ์ ๋๋ค.
์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ํ ์๋ฏธ๊ฐ ์๋ค๋ ์ ์ ๋์ํฉ๋๋ค. ๋ฌธ์ ๋ฅผ ์ผ์ผํจ ์ ์ฌ์ฉ ์ฌ๋ก๋ ๊ฑฐ์ ๋ฐ์ํ์ง ์์์ผ ํ๋ ๋งค์ฐ ๋ ํนํ ์ฝ๋ ์ฌ๋ก์์ต๋๋ค. ๋ด ์ฝ๋ ๊ธฐ๋ฐ์ ์ฝ๊ธฐ ์ ์ฉ props ๋ฐ state์ ์ ์ฉํจ์ผ๋ก์จ ๊ฐ์งํ ์ ์๋ ํ์ดํ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ๊ฒ์ํ ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ์ ํ์ด์๋ค๋ ์ ์๋ ์์ฌ์ ์ฌ์ง๊ฐ ์์ต๋๋ค.
Patsisson, VS, VS Code ๋๋ ๋ค๋ฅธ ํธ์ง๊ธฐ๋ฅผ ์ฌ์ฉ ์ค์ด์ ๊ฐ์?
์ ์์ ์ React๊ฐ ๊ธฐ๋ฅ์ ์ ๊ทผ ๋ฐฉ์์ ์ฅ๋ คํ๋ ๋ฐ๋ฉด ๋ช ๋ น์ ์ผ๋ก(์ํ) ์ธ๊ณ๋ฅผ ๋ณ๊ฒฝํ ๋ค์ ๋ ๋๋ง(forceUpdate)ํ๋ ๋น๋์ค ๊ฒ์๊ณผ ๊ฐ์ ์ํฌํ๋ก๋ฅผ ํ์ฉํ๋ค๋ ๊ฒ์ ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ์ด์ TS์์ ๊ธ์ง๋ฉ๋๋ค. ์ผ์ข ์ func-damentalism :)
๊ทธ๋ฌ๋ฉด ํ์ฌ ์ํ๊ณ๋ฅผ ์๋ ๊ฐ๋ฅํ๊ฒ ๋ง๋ค๊ธฐ ์ํ ๋์์ ์๊ฐํ ๊ฒ์ ๋๋ค.
๋ฌธ์ 2๋ strictNullChecks
์์๋ง ์ค๋ฅ๋ฅผ ๋์ง๋๋ค.
[TS] Cannot invoke an expression whose type lacks a call signature. Type '((val: any) => void) | undefined' has no compatible call signatures.
+1 strictNullChecks๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
@์๋ฆฌ์นธ๋์จ ?
์์์ ์ธ๊ธํ๋ฏ์ด ์ด๊ฒ์ ํด๋ง๊ณผ ๊ด๋ จ์ด ์์ผ๋ฉฐ ์ด๋ DT์ ๋ฒ์๋ฅผ ๋ถ๋ช ํ ๋ฒ์ด๋ฉ๋๋ค. VSCode๋ฅผ ์ฌ์ฉ ์ค์ด๊ณ ๊ณง ์ถ์๋ TS ํ์์ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ๋ฅผ ์ค์นํ๋ ๊ฒฝ์ฐ ์์ ๋ด์ฉ์ ์์ฑํ ๋ strictNullChecks์์ ์ด ๋ฌธ์ ๋ฅผ ๋ณด์ง ๋ชปํ์ต๋๋ค.
๋๋ ์ฐฝ๋ฌธ์ด ์์ผ๋ฏ๋ก VS์ ์ ์ ํ๊ฒ ๋งํ ์ ์์ต๋๋ค.
์ด Pick
ํจ์น๋ VSCode์์ ์ ์์ ์ค๋จํ์ต๋๋ค. this.setState({ | })
(Ctrl + Space) ํ๋ฉด State๊ฐ ๋ช
ํํ๊ฒ ์ ์๋์ด ์๊ณ Partial<State>
๋ฅผ ์ฌ์ฉํด๋ ์๋ฌด ๊ฒ๋ ํ์๋์ง ์์ต๋๋ค. setState
๋ ๋ฉค๋ฒ์ ์ํ๋ฅผ ์ ํ์ ์ผ๋ก ์ค์ ํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
IMHO ์ฌ๋ฐ๋ฅธ ์ฝ๋๋ setState(state: Partial<S>, callback?: () => any): void;
์ฌ์ผ ํฉ๋๋ค.
์๋ pull request ๋ธ๋์น์์ ๋ ผ์ํ ๊ฒ์ฒ๋ผ ์ฐ๋ฆฌ๋ Partial๋ก ์์ํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ํ ๊ฐ์ฒด๊ฐ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ:
์ธํฐํ์ด์ค ์ํ {
foo: ๋ฌธ์์ด;
}
๊ทธ๋ฐ ๋ค์ ๋ถ๋ถ์ ์ผ๋ก ๋ค์์ ์ํํ ์ ์์ต๋๋ค.
setState({foo: ์ ์๋์ง ์์});
๋ถ๋ช ํ ์๋ชป๋ ๊ฒ์ ๋๋ค.
์ฃ์กํฉ๋๋ค. ๋ค์ ์ฝ๊ธฐ ์ ์ฉ์ ๋ํด
React๋ Redux์ setState๋ง์ด ์๋๋๋ค. React๋ ๋ํ mobx ๋ฐ ๊ธฐํ ๊ด์ฐฐ ๊ฐ๋ฅํ ํจํด์ด๋ฉฐ ์ํ ์์ฑ ํ ๋น์ด ์ฃผ์ ๊ธฐ๋ฅ ์ ๋๋ค. ๋ ผ์๋ ๋ณ๊ฒฝ ์ฌํญ์ typescript๋ก mobx ์ฌ์ฉ์ ์์ ํ ์ข ๋ฃํฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์๋ ๋ฐ์ ์ฝ๋์ ์กด์ฌํ์ง ์๋ ๋์์ .d.ts ํ์ผ์ ์ถ๊ฐํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? .d.ts๋ ์๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฐ์ํ๋ ๊ฒ์ด์ง๋ง ์์ฑ์์ ๊ด์ ์ ๋ฐ๋ผ ์ฌ๋ฐ๋ฅธ ์ฝ๋ฉ ์คํ์ผ์ ๊ฐ๋ฅด์น๋ ๊ฒ์ ์๋๋๋ค!
@lezious , ๋๋ ๋น์ ์ ์ ์ฅ์ ์ดํดํ์ง ๋ชปํฉ๋๋ค. ์ฝ๋ ์ํ์ ์ ๊ณตํ ์ ์์ต๋๊น? ๊ทธ๋ฆฌ๊ณ ์ํ๊ณผ ๊ด๋ จํ์ฌ ํ์ดํ์ ๋ํด ์๋ชป๋ ์ ์ ๋ฌด์์ ๋๊น? ๊ฐ์ฌ ํด์!
๊ด์ฐฎ์์:
์ด๊ฒ์ ๋ด ์ํ ํด๋์ค์ ๋๋ค
class UserInfoBlockState
{
<strong i="7">@observable</strong> <- this is mobx way to declare state
public updating: boolean;
<strong i="8">@observable</strong>
public deleted: boolean;
}
๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ๋ด ๊ตฌ์ฑ ์์์ ๋๋ค
<strong i="12">@observer</strong> <-- this is mobx way to make component react to state change
export class UserPanel extends React.Component<IUserInfoBlockProps, UserInfoBlockState>
{
......
private updateUser()
{
this.state.updating = true;
UsersAPI.update(this.props.user)
.then(() =>
{
this.state.updating = false; <--- this is the mobx way to work with the state
}
).catch(() =>
{
this.showErrror("Server error");
this.state.updating = false;
});
}
....
}
๊ทธ๋ฆฌ๊ณ ์ด์ ์ฐ๋ฆฌ(react+mobx๋ก ์์ฑ๋ ๊ฑฐ๋ํ ํ๋ก์ ํธ๊ฐ ์๋ ์ฐ๋ฆฌ ํ์ฌ)๋ ์ ๋ฆด๋ฆฌ์ค ์ํด์ด ์์๋ ๋ DT ๋ฐ React๋ฅผ ์ ๋ฐ์ดํธํ์ผ๋ฉฐ ... 3000๊ฐ ์ด์์ ์ปดํ์ผ ์ค๋ฅ "์์ฑ์ด ์ฝ๊ธฐ ์ ์ฉ์ ๋๋ค". ์. ๋น์ ์ด ๋์๊ฒ ์ ์ํ ๊ฒ - ์ ์ฒด ํ๋ก์ ํธ๋ฅผ redux๋ก ๋ค์ ์์ฑํ๊ฑฐ๋ react.d.ts๋ฅผ ์ ๋ฐ์ดํธํ์ง ์๊ฑฐ๋ ํญ์ ๋ถ๊ธฐ๋ ๋ฒ์ ์ ์ ์งํ๊ณ ์ง์ํฉ๋๊น?
@mweststrate , ์ด๊ฒ์ ํ์ธํ์ญ์์ค.
@Iezious ๊ทํ์ ์ ์ฅ์ ๊ฐ์ฌ๋๋ฆฌ๋ฉฐ ์ง์ ํ์๊ธฐ ๋ฐ๋๋๋ค. ๋๋ ๋น์ ๊ณผ ํจ๊ป ์ผํ๋ ค๊ณ ํด์. ์ด๊ฒ์ Redux์ ์๋ฌด ๊ด๋ จ์ด ์์ง๋ง ์์ํ React์ ๋๋ค.
๋๋ DT๊ฐ ์ด์ ์ ์๋ํ๋ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ฐจ๋จํ๋ ๊ฒ์ ์ํ์ง ์์ง๋ง, ๋ฐ์๊ณผ ํจ๊ป mobx์ ์ฌ์ฉ์ ์ค๋ช ํ๋ ๋ฐฉ๋ฒ์ด ๋ฐ์ ๋ฌธ์์ ์ผ์นํ๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ๊ทธ๊ฒ).
React๋ ๋ฌธ์์์ state๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ 3๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค๊ณ ๋ถ๋ช ํ ๋ช ์ํ๊ณ ์์ผ๋ฉฐ, ์ฒซ ๋ฒ์งธ๋ "์ํ๋ฅผ ์ง์ ์์ ํ์ง ๋ง์ญ์์ค"์ ๋๋ค.
์ด๊ฒ์ ํ์ฌ ์ฝ๋ ๊ธฐ๋ฐ์ด ์๋ํ๋ ๋ฐฉ์์ด ํฅํ ๋ฒ์ ์ react์์ ๊นจ์ง ๊ฐ๋ฅ์ฑ์ด ๋๋ค๊ณ ๋ฏฟ๊ฒ ๋ง๋ญ๋๋ค. https://github.com/mobxjs/mobx-react ๋ฅผ ์ดํด๋ณด๋ฉด ์ํ๋ฅผ ์ด๋ฐ ์์ผ๋ก ์ฌ์ฉํ๋ค๋ ์ ์์ ๋ณผ ์ ์์ต๋๋ค. ์ฌ์ค, ๊ทธ๋ค์ ๋น์ ์ด ์์ฑ์ ์ฌ์ฉํ๊ธฐ๋ฅผ ์ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
https://mobx.js.org/getting-started.html ์ ๊ฒํ ํ๊ณ "mobx ๋ฐ์ ์ํ"์ ๋ํด ์ธํฐ๋ท ๊ฒ์์ ํด๋ณด๋ฉด, mobx๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์ ์ํ๋ ๋ฌธ์๋ฅผ ์ฐพ์ง ๋ชปํ์ต๋๋ค.
DT๋ ๊ธฐ๊ปํด์ผ ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ ์ ์ ๋ฌํ๊ณ ์ต์ ์ ๊ฒฝ์ฐ ์ค์ ๊ตฌํ์ ์ ๋ฌํด์ผ ํ๋ฉฐ, ๋ฐ์์ ๊ตฌ๋งคํ๊ณ ๊ตฌ์ฑ ์์๋ฅผ ํ์ฅํ๋ ๊ฒ์ ๋ฌต์์ โโ๊ณ์ฝ์ ์กด์คํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค๋ ๊ฒ์ด ๋ถ๋ช ํฉ๋๋ค.
๋ด๊ฐ ๋น์ ์๊ฒ ๋ฌด์์ ์ ์ํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋ด๊ฐ ์๊ฐํ ์์๋ ๋ช ๊ฐ์ง ์ต์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
state
๋ณ์ ์ธ์๋ฅผ ์ฃผ์ฅํ๋ ๊ฒฝ์ฐ "์ ๋ ดํ" ์ต์
์ React.Component
๋ฅผ ๊ฒ์ํ์ฌ MyComponent
๋ก ๋ฐ๊พธ๊ณ $ MyComponent
๋ฅผ ํ์ ํด๋์ค๋ก ์ ์ํ๋ ๊ฒ์
๋๋ค. ์ฝ๊ธฐ ์ ์ฉ ์ ์ฝ ์์ด React.Component
์ค.this.state
์ฌ์ฉ์ ์ค๋จํ๊ณ ์ค์ React.Component
์ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ์ด๊ฒ์ ์ฝ๊ฐ ๊ณ ํต์ค๋ฌ์ธ ์ ์์ง๋ง ์ ์ด๋ ํ๋ก์ ํธ์ ์๋ก์ด ์ฌ๋๋ค์ ์จ๋ผ์ธ์ ์ค๋ช
๋ ๋๋ก ์ฝ๋ ๊ธฐ๋ฐ์ ํจํด์ ๋ณผ ์ ์์ ๊ฒ์
๋๋ค.state
๋ฅผ ๋ค์ ์ ์ธํ ์ ์์ต๋๋ค.this.state
๋ฅผ ๊ฒ์ํ์ฌ this.somethingElse
๋ก ๋ฐ๊พธ๊ณ ์๋์ผ๋ก ์ ์ธํ ์ ์์ต๋๋ค.๊ทธ๊ฒ์ด ๋ด ํ๋ก์ ํธ๋ผ๋ฉด ์๋ง๋ 2๋ฒ์ ํ์ ๊ฒ์ ๋๋ค. ๋น๋ก mobx์ ๋ํด ํ์คํ ์์ง๋ ๋ชปํ์ง๋ง์.
์ฃ์กํฉ๋๋ค(๋ค๋ฅธ ์ฌ๋๋ค์ด ๋์ํ์ง ์์ ๊ฒ์ด๋ผ๋ ์๋ฏธ๋ ์๋). ๋๋ ๊ทธ ๋ถ๋ถ์ ๋๋๋ฆด ์ด์ ๋ฅผ ์ฐพ์ผ๋ ค๊ณ ๋ ธ๋ ฅํ์ง๋ง ์ง๊ธ์ ํ์นํ์ง ๋ชปํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
Mobx ํจํด๊ณผ ๋งค์ฐ ์ ์ฌํ React ์ํ ๋ณ๊ฒฝ ๋ฐ ๋ ๋๋ง์ ๊ตฌ๋ํ๊ธฐ ์ํ RxJ ๊ด์ฐฐ ๊ฐ๋ฅ ํญ๋ชฉ์ ์ฌ์ฉ์ ์ง์ ์์ฉ ํ๋ก๊ทธ๋จ์ธ ์ฐ๋ฆฌ์ ์ ๋ต์ ๋ค์ ์ธ๊ธํ๊ฒ ์ต๋๋ค. ๋ทฐ(React) ๋ ์ด์ด์์ ์ ๋ ฅ์ ๋ฐ๊ธฐ ์ํด ์ก์ ์ ์ฌ์ฉํฉ๋๋ค. ์์ ์ ์ ๋ ฅ์ ์๋นํ๊ณ ๊ด์ฐฐ ๊ฐ๋ฅ ํญ๋ชฉ์ ์์ฑํ ๋ค์ ๋ค๋ฅธ ์ํ ๊ด์ฐฐ ๊ฐ๋ฅ ํญ๋ชฉ์ ์ถ๊ฐ๋ก ๊ตฌ๋ํ๋ ํจ์์ ๋์์ด์ ๋๋ค. ์ด ํจํด์ ์ฌ์ฉํ๋ฉด ๊ด์ฐฐ ๊ฐ๋ฅํ ๊ฐ๋ง ์ฟผ๋ฆฌํ๊ณ ์ํ ์์ ์ ์คํํ๊ธฐ ๋๋ฌธ์ React ๋ ์ด์ด ๊ด์ ์์ ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ๋ด๋ถ ์ํ์๋ ์ฝ๊ธฐ ์ ์ฉ ์ ์ฝ ์กฐ๊ฑด์ด ์๊ธฐ ๋๋ฌธ์ ๋ด๋ถ์ ์ผ๋ก ์ํ๋ ์์ ์ ๊ฒฐ๊ณผ๋ก ์์ฒด์ ์ผ๋ก "๋ณ๊ฒฝ"๋ ์ ์์ต๋๋ค.
์ง์ ํ ์ ์์ด์. ๋๋ ํ๋ก๋์ ์ ์๋ ํ๋ก์ ํธ๋ฅผ ๊ฐ์ง๊ณ ์๊ณ ์์ฒญ๋ ์์ ํ ์๊ฐ์ ๋ณด๋ด์ผ ํ๊ณ , ์ด๊ฒ์ ์ด ๋ณ๊ฒฝ ์ดํ์ ๋์ ์๋ฏธํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ์ด์ ๋ ๋ฌด์์ ๋๊น? ์ด ๋ณํ๋ ๋ฐ์์ ํ์ค์ ๋ฐ์ํฉ๋๊น? ์๋์. ๋ฐ์์ ์๋ ์ ํ ์ฌํญ๊ณผ ๋์์ ์ถ๊ฐํฉ๋๋ค. ์ด๊ฒ์ด ์ณ๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ์ด๋ป๊ฒ๋ ์ถ๊ฐ๋๋ ์ ํ ์ฌํญ์ ๋๋ค.
DT ํ๋ก์ ํธ์ ๋ชฉํ๋ ๋ฌด์์ ๋๊น? JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ๋ฅํ ํ ์ ํํ๊ฒ ์ค๋ช ํ๊ฑฐ๋ ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฌ๋ฐ๋ฅธ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ํ ์ฐ๋ฆฌ์ ๋น์ ์ ์ค๋ช ํ๋ ค๋ฉด? "Definitely Typed"๋ผ๋ ์ด๋ฆ์ ๋ฐ๋ฅด๋ฉด ์ฒซ ๋ฒ์งธ์ ๋๋ค. ๋ฐ๋ผ์ ์ด ์ ํ์ด ์๋ JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์กด์ฌํ์ง ์์ผ๋ฉด DT์๋ ์กด์ฌํด์๋ ์ ๋ฉ๋๋ค(MUST NOT). ์ด๊ฒ์ด ์ ์์ ์ ๋๋ค. ์ด ์์ ์์ ๋ด๊ฐ ์๋ชปํ ๋ถ๋ถ์ ๋ฌด์์ ๋๊น?
๋๋ ๋น์ ์ด ์ข์ ๊ฐ์ ๋๋๋ค๋ ๊ฒ์ ์ดํดํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋ฌธ์๋ฅผ ์ฝ์ ๋ ๋ฐ์์ด ์ฌ์ฉ๋๋๋ก ์๋๋ ๋ฐฉ์์ ๋๋ค. ๊ทํ์ ํ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋จ์ฉํ๊ณ ๋ฌต์์ ๊ณ์ฝ์ ์๋ฐํ๊ธฐ ๋๋ฌธ์ DT๋ฅผ ๋ ๊ตฌ์ฒด์ ์ผ๋ก ๋ง๋๋ ๋ฐฉ๋ฒ์ ๊ฑฐ์ ์ ์ ์์ต๋๋ค.
์ํ๊ฐ ์ง์ ๋ณ๊ฒฝ ๊ฐ๋ฅํด์ผ ํจ์ ์ ์ํ๋ ๋ฐ์ ํ์ด ๋ด๋์ 1์จ์ค์ ๋ฌธ์๋ฅผ ๋ณด์ฌ์ฃผ์๋ฉด ์ฆ์ ์ฝ๋๋ฅผ ๋ค์ ๋ณ๊ฒฝํ๊ฒ ์ต๋๋ค.
https://facebook.github.io/react/docs/react-component.html#state
๋์ค์ setState()๋ฅผ ํธ์ถํ๋ฉด ๋ณ๊ฒฝ์ ๋์ฒดํ ์ ์์ผ๋ฏ๋ก this.state๋ฅผ ์ง์ ๋ณ๊ฒฝํ์ง ๋ง์ญ์์ค. this.state๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ๊ฒ์ฒ๋ผ ์ฒ๋ฆฌํฉ๋๋ค.
๋ฐ์์ด this.state
๋ณ๊ฒฝํ ์ ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๋ ๊ฒ์ด ๋งค์ฐ ๋ถ๋ช
ํด ๋ณด์
๋๋ค. React๋ this.state
์ _properties_๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ์ง ์์ต๋๋ค(์ด๋ redux ๊ฐ์ ). ๋ค์ ์์
์ ์์ ๋กญ๊ฒ ์ํํ ์ ์์ต๋๋ค.
this.state.user.name = "foo";
๊ด์ฉ์ ๋ฐ์์ผ๋ก.
๋ด๊ฐ ์ ํธํ๋ ๊ฒ์ API๋ฅผ ์ ํํ๊ฒ ์
๋ ฅํ๊ณ (์ด ๊ฒฝ์ฐ Readonly
์๋ฏธ) ๋ฐ์ ํ์ด ๋ช
์ํ ๋ชจ๋ ๋ถ๋ณ๋์ ํํํ๋ ๊ฒ์
๋๋ค.
@ericanderson ์ฃ์กํฉ๋๋ค. ์ด์ ์์ผ ์์์ฐจ๋ ธ์ต๋๋ค. FWIW ๋๋ ๋ณํ๊ฐ ํฉ๋ฆฌ์ ์ด๊ณ ๋๊ตฌ๊ฐ ๋ฐ๋ผ ์ก์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ ์ํด ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ setState
์ค๋ฒ๋ก๋๋ฅผ ๋ ์ด์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ ๊ณ ๋ คํ๊ณ ์๋ค๊ณ ๋ค์์ต๋๊น? ๋ฏธ๋๋ ๋ชจ๋ ๊ณ์ ์ setState
์ถ์ ์คํ์ผ์
๋๋ค.
@amoreland ๋์ํ์ง ์์ต๋๋ค. ๋น: https://facebook.github.io/react/docs/state-and-lifecycle.html#do -not-modify-state-directly
์ํ๋ฅผ ์ง์ ์์ ํ์ง ๋ง์ญ์์ค.
์๋ฅผ ๋ค์ด ๋ค์์ ๊ตฌ์ฑ ์์๋ฅผ ๋ค์ ๋ ๋๋งํ์ง ์์ต๋๋ค.
// Wrong this.state.comment = 'Hello';
๋์ setState()๋ฅผ ์ฌ์ฉํ์ญ์์ค.
// Correct this.setState({comment: 'Hello'});
this.state๋ฅผ ํ ๋นํ ์ ์๋ ์ ์ผํ ์ฅ์๋ ์์ฑ์์ ๋๋ค.
@johnnyreilly ๋๋ ์์๋ค. ๊ทธ ํฅ๋ฏธ ๋กญ๊ตฐ์. ์์ฒ?
์ต๊ทผ์ ๋ฆฌ์กํธ ์ปจํผ๋ฐ์ค์์ ๋ ผ์๋ ๋ด์ฉ ์ค ํ๋์ ๋๋ค. YouTube์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. Lin Clark์ ์ฐ์ค์ด์์ ๊ฒ์ ๋๋ค. 1์ผ ์ฐจ์ ์ฒซ ๋ฒ์งธ ๋ํ ์ค ํ๋ - v16์ ๋์ํ ์์ ๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋ค๋ฃน๋๋ค. ์ฌ์ ๋ฑ
https://www.reddit.com/r/reactjs/comments/5zqgsb/react_fiber_functional_setstate/ @gaeron์ด ์ฌ๊ธฐ์์ ์ธ๊ธ
@gaearon ์ฃ์กํฉ๋๋ค.
mobx๊ฐ ์ํ ๋ณ๊ฒฝ์ ์ํํ๋ ์ด์ ๋ ์ต์ ๋ฒ๋ธ์ด ์ํ๋ฅผ ์์ ํ _๊ต์ฒด_ํ๋ ๋์ React ์
๋ฐ์ดํธ๋ฅผ ๊ตฌ๋ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ํ๋ ๋ ๋๋ง์ ๊ตฌ๋ํ๋ ์์ง์ด ๋ฉ๋๋ค. ๋ฐ๋ผ์ this.state.updating = true;
์ ๊ฐ์ ์์
์ ์ํํ๋ฉด ์ค์ ๋ก ์ํ ๊ต์ฒด์ ๋์ผํ ์์
์ ์ํํ๋ ๊ฒ์ด์ง๋ง ์ํ๋ ์ด์ ์ฝํ
์ธ ์์ ์ํ๊ฐ ๋ณ๊ฒฝ๋์์์ ๊ตฌ์ฑ ์์์ ํต์งํ์ฌ ์ ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํ ๋งํผ ์ถฉ๋ถํ ๋๋ํฉ๋๋ค. ๋๋ ์ด๊ฒ์ด _conventional_ React ์ฌ์ฉ๋ฒ์ด ์๋๋ผ ํจ์ฌ ๋ ํฌ๊ด์ ์ด๊ณ ๋ ๋์ ์์ค์ React ์ฌ์ฉ๋ฒ์ด๋ผ๋ ๋ฐ ๋์ํฉ๋๋ค. ๋๋ ์ ํต์ ์ธ React ์ฌ์ฉ๋ฒ์ด ์์์ ๊ตฌ์ฑ ์์๊ฐ ์๋ ์๊ท๋ชจ ํ๋ก์ ํธ์๋ง ์ ์ฉํ๋ค๊ณ ์ฃผ์ฅํฉ๋๋ค. ๊ฐ๊ฐ ์์ญ ๊ฐ์ ๋ฐ์์ฑ ๋์ฐ๋ณ์ด ๋๋ผ์ด๋ฒ๊ฐ ์๋ 100๊ฐ์ ๊ตฌ์ฑ ์์๋ก ๋๋๋ฉด ๊ธฐ์กด์ React ์ํ ๋ณ๊ฒฝ(์ฆ, setState)์ ๋ ์ด์ ์์ ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ผ๋ฉฐ _smart_ state(mobx๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ํํ๋ ์์
)์ ๊ด๋ จ๋ ์ํคํ
์ฒ ๋ณ๊ฒฝ์ ์์ฉํด์ผ ํฉ๋๋ค. ).
์ฆ, ํ์ดํ ๋ณ๊ฒฝ์ด React ์์คํ ์ ๊ณ ๊ธ ์ฌ์ฉ์ ์ํฅ์ ๋ฏธ์น๊ธฐ ๋๋ฌธ์ ๊ทธ๊ฐ ํ๋ ์ด์ ๋ฅผ ์ดํดํฉ๋๋ค. ๊ด์ฐฐ ๊ฐ๋ฅํ ์ํ ํ ๋น์ ๊ธฐ์ ์ ์ผ๋ก _mutating_ ์ํ๊ฐ ์๋๋ผ RHS ๊ฐ์ ๋ํ ๊ด์ฐฐ ๊ฐ๋ฅํ ์ด๋ฒคํธ๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋๋ค. mobx๊ฐ ์ด๋ฌํ ๊ด์ฐฐ ๊ฐ๋ฅํ ์ด๋ฒคํธ๋ฅผ ๋ฐํํ๊ธฐ ์ํด ์ ํํ ๊ตฌ๋ฌธ์ด React ๋ถ๋ณ ์ํ์ ๋ช ์์ ์๋์ ์ถฉ๋ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
@Iezious ์ด๋ฌํ ์ ํ์ ๋ฌธ์ ์ ๋ํ ๋น ๋ฅธ ์์ ์ด ํ์ํ ๊ฒฝ์ฐ React ์ ํ์ ๋ณด๊ฐํ๊ณ React.Component
์ ํ ์ ์์ ๋ํ ํ์ฅ์ ์ฌ์ฉํ๋๋ก ๊ตฌ์ฑ ์์๋ฅผ ๋ฆฌํฉํฐ๋งํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
import * as React from 'react';
declare module 'react' {
class MutableStateComponent<P, S> extends React.Component<P, S> {
state: S;
}
}
(React as any).MutableStateComponent = React.Component;
์ด์ state
๋ฉค๋ฒ๊ฐ ๋ ์ด์ readonly
๋ก ํ์๋์ง ์๋๋ค๋ ์ ์ ์ ์ธํ๊ณ ์ผ๋ฐ ๊ตฌ์ฑ ์์์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
export class MyComponent extends React.MutableStateComponent<MyProps, MyState> {
// this.state.name is writable
}
@patsissons ๋ค, ๋ฐ๋ก ๊ทธ ์ด์ ์ ๋๋ค.
์ ๋ ์ํ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ setState๋ฅผ ํธ์ถํ๋ mobx ์ต์ ๋ฒ๋ธ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์ ๊ฑฐ๋ํ ํ๋ก์ ํธ ์ฝ๋๊ฐ ํจ์ฌ ๋ ๋ช ํํ๊ณ ์ดํดํ๊ธฐ ์ฌ์ ๋ณด์ด๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ํ๊ณ ์์ต๋๋ค.
๋๋ ๋ด ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค ์ ์๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ๋ํ npm ์๋ฒ์์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ง๋ค ์ ์์ผ๋ฉฐ ์ด ์คํฌ๋ฆฝํธ๋ ํญ์ ์ฐ๋ฆฌ ํ์ฌ์ ๋ํด ์ด ๋ณ๊ฒฝ ์ฌํญ์ ๋๋๋ฆด ๊ฒ์ ๋๋ค. "this.state.state.updated"์ ๊ฐ์ ํดํน๊ณผ ๋ค๋ฅธ ๋ง์ ํดํน์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ ๋ ์ด ๋ณ๊ฒฝ์ด ์ค์ ๋ก ๋ฐ์ ๋ฐฉ์์ ๋ฐ๋ฅด๋ mobx์ ๊ฐ์ ๊ด์ฐฐ ๊ฐ๋ฅํ ํจํด ์ฌ์ฉ์ ์ํฅ์ ๋ฏธ์น๋ค๊ณ ๋งํ๊ณ ์ถ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ง๊ธ์ ์ด ๋ณ๊ฒฝ์ ์ปดํ์ผํ ์ ์๊ณ ์๋ํ๋ ค๋ฉด ๋ช ๊ฐ์ง ํดํน ๋ฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋์ ์ ๋ ์ด ๋ณํ๊ฐ ์ณ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์๋ง๋ ๋ด๊ฐ ์ ์ํ MutableStateComponent
๋์ Observable React ํจํด์ ๋ ์ ๋ง๋ ObservableComponent
๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
Readonly
๋ฅผ ์ญ์ ํ๋ฉด ์ผ๋ฐ ๋ฐ์(๋ฐ/๋๋ mobx๋ฅผ ์ ์ธํ ๋ค๋ฅธ ์ํ ๊ด๋ฆฌ ์์คํ
)๊ณผ ํจ๊ป ๋ฐ์ ์ ํ์ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ด ์ค๋ฅ์ ๋
ธ์ถ๋ฉ๋๋ค. ๋๋ ๊ฑฐ๋ํ ํ๋ก์ ํธ์์ mobx๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉฐ ๋๊ตฐ๊ฐ๊ฐ ์คํ๋ฅผ ๋ง๋ค๊ณ ์ค์๋ก this.state.foo = bar
์ ์ฌ์ฉํ ๋ ์ปดํ์ผ๋ฌ ์ค๋ฅ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
ํ์ค ๋ฐ์๊ณผ ๋นํ์ค ๋ฐ์ ์ฌ์ฉ ์ฌ์ด์ ํผํ ์ ์๋ ์ ์ถฉ์ ์ด ์๋ ๊ฒฝ์ฐ ํ์ค ๋ฐ์ ์ ํ์ ์ ์์ ์์กดํด์ผ ํฉ๋๋ค.
๋ํ mobx๋ฅผ ๊ด์ฉ์ ์ผ๋ก ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค.
Readonly๋ฅผ ์ญ์ ํ๋ฉด ์ผ๋ฐ ๋ฐ์(๋ฐ/๋๋ mobx๋ฅผ ์ ์ธํ ์ฌ๋ฌ ์ํ ๊ด๋ฆฌ ์์คํ )๊ณผ ํจ๊ป ๋ฐ์ ์ ํ์ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ด ์ค๋ฅ์ ๋ ธ์ถ๋ฉ๋๋ค. ๋๋ ๊ฑฐ๋ํ ํ๋ก์ ํธ์์ mobx๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉฐ ๋๊ตฐ๊ฐ ์คํ๋ฅผ ๋ง๋ค๊ณ ์ค์๋ก this.state.foo = bar๋ฅผ ์ฌ์ฉํ ๋ ์ปดํ์ผ๋ฌ ์ค๋ฅ์ ๊ฐ์ฌํฉ๋๋ค.
๋ค์ ํ ๋ฒ - ๋น์ ์ ์ฝ๋ ์์ฑ์ ๊ฐ๋ฅด์น๊ณ ์์ต๋๋ค
์ด ํ๋ก์ ํธ๋ ์ฝ๋ ์์ฑ์ ๊ฐ๋ฅด์น๋ ๊ฒ์ด ์๋๋ผ JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ธฐ์กด ๊ธฐ๋ฅ์ ์ค๋ช ํ๋ ๊ฒ์ ๋๋ค. ๋ ผ์๋ ์ ํ ์ฌํญ์ ์๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ผ๋ฏ๋ก ์ญ์ ํด์ผ ํฉ๋๋ค.
๊ทธ๊ฒ ๋ค์ผ.
@patsissons
์ด๋ฌํ ์ ํ์ ๋ฌธ์ ์ ๋ํ ๋น ๋ฅธ ์์ ์ด ํ์ํ ๊ฒฝ์ฐ React ์ ํ์ ๋ณด๊ฐํ๊ณ React.Component ์ ํ defs์ ๋ํ ํ์ฅ์ ์ฌ์ฉํ๋๋ก ๊ตฌ์ฑ ์์๋ฅผ ๋ฆฌํฉํฐ๋งํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
์ณ์ง ์๋ค. ๋ด๊ฐ ์๋ ๊ธฐ์ ์ ์ธ๊ณ์๋ "๋น ๋ฅธ ์์ "์ด ์์ต๋๋ค. SDK์์ ๋ฌด์ธ๊ฐ๊ฐ ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ด์ ๋ฒ์ ๊ณผ ํธํ ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ช ๋ ์ด ๊ฑธ๋ฆฝ๋๋ค. 2๋ฐฑ๋ง ๋ผ์ธ ์ด์์ ์ฝ๋ ํ๋ก์ ํธ์๋ ๋น ๋ฅธ ์์ ์ด ์์ต๋๋ค. ๋ช ์ฃผ๊ฐ์ ๋ณ๊ฒฝ, ํ ์คํธ, A/B ์ ํ ํ ์คํธ, ๋ง์ ์ฌ๋๋ค์ ์ํ ๋กค์์์ ๋๋ค. ์ค์ ๋์ด ๋ญ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๊ตฐ๊ฐ๊ฐ ์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์กด์ฌํ์ง ์๋ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋์ง ์๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ๊ฐํ๊ธฐ ๋๋ฌธ์ ์ด ๋ชจ๋ ์์ฒญ๋ ๋ ธ๋ ฅ์ ๊ธฐ์ธ์์ต๋๊น?
์ forceUpdate๊ฐ ๋ฐ์์ ์ฌ์ ํ ์กด์ฌํ๋ค๊ณ ์๊ฐํฉ๋๊น? ๊ทธ๋ค์ ์ฌ๋ฐ๋ฅธ ์คํ์ผ์ ๋ํด conf์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ง๋ง ๋ค๋ฅธ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ณ๊ฒฝํฉ๋๋ค. ์์? ๋๊ธฐ์ ์ด๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋์ด์ผ ํจ์ ์๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
@ericanderson ์ด ์ผ์ต๋๋ค
this.state.state.value = 1
๊ทธ์ ๊ด์ ์์๋ ์ ๋นํ์ง ์๋ค. ๋ค์์ ๊ทธ๋ TS์์ ๋๊ตฌ๋ฅผ ์ป๊ณ ์ด ์ฝ๋๋ฅผ ๋ฐฉ์งํ๋ ์ ํ์ ์ถ๊ฐํ ๊ฒ์ ๋๋ค. ๋๋ ๊ตฌ์ฑ ์์๋ฅผ ์ต์ข ํด๋์ค๋ก ๋ง๋ค๊ฑฐ๋ "์ฌ๋ฐ๋ฅธ ์คํ์ผ์ด๊ณ ์ฌ๋๋ค์ด ์ค์ํ์ง ์๋๋ก"ํ๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ๊ฒ์ผ๋ก ๋ง๋ญ๋๋ค.
์ฌ๋๋ค์ ์ค์ ๋ฐฉ์ง - FB์ ์์ ์ ๋๋ค. ์ํ๋ ๊ฒฝ์ฐ ํ๋ก์๋ฅผ ์ฝ๊ฒ ์ถ๊ฐํ๊ณ ์ํ ๋์ฐ๋ณ์ด๋ฅผ ํ์ฉํ์ง ์์ ์ ์์ต๋๋ค. DT์ ๋ชฉ์ ์ ์ค๋ช ์ ์ถ๊ฐํ๋ ๊ฒ๋ฟ์ ๋๋ค.
@์ด์ง์ด์ค
์์ ์ React ํ์ด JavaScript๋ก ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋๋ก ๋ง๋ค ์๋ ์์ง๋ง ๊ฐ๋ฅํ๋ค๋ฉด ๊ทธ๋ ๊ฒ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ๋ฐ๋ฉด์ TypeScript๋ ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋๋ก ๋ง๋ค ์ ์์ผ๋ฏ๋ก ์ด๋ฌํ ๋ณ๊ฒฝ์ด ์ ํ ์ ์์ ์ ์ฉ๋ ์ด์ ์ ๋๋ค. ์ํ ๊ตฌ์ฑ์์ ๋ํ ์ง์ ์์ ์ ํ์ฉํ์ง ์๋ ๊ฒ์ด React ํ์ ์ ๋์ ์ธ ์๋์์ง๋ง( ์ํ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ ๊ฒ์ ๋ํ ๊ณต์ ๋ฌธ์์์ ์ ์ ์๋ฏ์ด), ํด๋น ์ ์ฝ ์กฐ๊ฑด์ ๋ถ๊ณผํ ์ธ์ด ๊ตฌ์ฑ์ด ์์์ต๋๋ค. ์ด ์ ์ฝ ์กฐ๊ฑด์ ์๋ ค์ง์ง ์์์ผ๋ฉฐ ์ฒ์๋ถํฐ ์ ๋ฌธ์ํ๋์์ต๋๋ค. React์ _conventional_ ์ฌ์ฉ ๋ฒ์ ๋ฐ์์ ์์ ํ๋ ์ฌ๋๋ค์ ๊ฒฝ์ฐ ์ต์ํ React ๊ณต์ ์ฌ์ฉ ๊ถ์ฅ ์ฌํญ์ ์ค์ํด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ ํ์๊ฒ ์ด๋ ์ํ๋ฅผ ์ง์ ๋ณ๊ฒฝํ์ง ์๊ณ ์ํ ๋ณ๊ฒฝ์ ์ถ์งํ ์ ์๋ ์๋ฃจ์ ์ ์ค๊ณํ๋ ๊ฒ์ ์๋ฏธํ์ต๋๋ค. ์ด๊ฒ์ ํนํ ์ด์ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ํ๊ธฐ ์ํด ์ํ๋์์ต๋๋ค(์ด ๋ณ๊ฒฝ์ด ์ฐ๋ฆฌ์๊ฒ ์ฝ๊ฐ์ ์ํฅ์ ์ฃผ๊ธด ํ์ง๋ง ๊ธฐ๋ณธ ์ค๊ณ๊ฐ ์๋ ๊ธฐ๋ฅ ์๋ช ์ ํตํด์๋ง).
๊ทํ์ ์ํฉ์์ ๋ฆฌํฉํ ๋ง์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋ณ๊ฒฝ์ด ์ด๋ฃจ์ด์ง๊ธฐ ์ ์ @types/react
๋ฅผ 15.0.1
์ ๊ณ ์ ํ๊ฑฐ๋ @types/react
๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋์ ์์ ์ ๋ณํ์ ์ ์งํ์ญ์์ค. defs ๋ฅผ ์
๋ ฅํ๊ณ Component
state
ํ์ดํ์ ๋ณ๊ฒฝํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ๋๋๋ฆฌ๋๋ก ๋๊ตฐ๊ฐ๋ฅผ ์ค๋ํ๋ ๋ฐ ์ฑ๊ณตํ์ง ๋ชปํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
forceUpdate
๋ ๋ด๋ถ ๊ตฌ์กฐ์ ์ํ๊ฐ ์์ ๋ ๋(๋๋ render()
๊ฐ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ ์ธ๋ถ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ๋) ๋ ๋๋ง์ ๊ตฌ๋ํ๊ธฐ ์ํ ๊ถ์ฅ ์ฝ๋ ๊ฒฝ๋ก๋ก ๋ฌธ์ํ๋์ด ์๊ธฐ ๋๋ฌธ์ ์กด์ฌํฉ๋๋ค. forceUpdate
์ ์ฌ์ฉ๋ฒ์ ์ฐ๋ฆฌ ํ์ด React์์ ์ฌ์ฉํ๋ ์ฌ์ฉ ํจํด๊ณผ ์ ํํ ์ผ์นํ๋๋ก ์ค๊ณ๋์์ต๋๋ค.
React ํ์ JS๋ก ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋๋ก ๋ง๋ค ์ ์์ต๋๋ค. ์ฝ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋์ง ์์ต๋๋ค.
๋ค์ ํ ๋ฒ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
this.state.state.value = 1
ํฉ๋ฒ ์ฌ๋ถ?
๋ผ๊ณ ์๊ฐํฉ๋๋ค๋ง ์ ์๊ฐ์ ์ด๋ฏธ ๋ช ํํฉ๋๋ค...
๋๋ ๊ฐ๋ณ์ฑ/๋ถ๋ณ์ฑ์ ๋ํ ๋ํ๊ฐ _์์ง_ ๊ด๋ จ์ด ์๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ๋ถ๋ช
ํ ์ด ๋ณ๊ฒฝ๊ณผ ๊ฒฐํฉ๋ TS ์ปดํ์ผ๋ฌ์ ๋ฒ๊ทธ( Readonly
๊ด๋ จ)๋ก ์ธํด ์ผ๋ฐ ๊ตฌ์ฑ ์์๋ฅผ ์์ ํ ์ฌ์ฉํ ์ ์๊ฒ ๋์ด ๋ง์ ๊ธฐ์กด ์ฝ๋๊ฐ ์์๋ฉ๋๋ค. ํ์คํ ๊ทธ๊ฒ์ ๋ณดํธ์ ์ผ๋ก ํ์ฉ๋๋ ์ ํจํ ์ฌ์ฉ ์ฌ๋ก์ด๋ฉฐ ์ง๊ธ์ ์ด๊ฒ์ ๋กค๋ฐฑํ ์ถฉ๋ถํ ์ด์ ๊ฐ ๋ฉ๋๋ค???
interface test1 {
num: number;
}
function add<T extends test1>(initial: T, add: number) {
var copy: Readonly<T> = initial;
//ERROR HERE: [ts] Operator '+' cannot be applied to types 'T["num"]' and 'number'.
return copy.num + add;
}
์ด์ ๋ํด Typescript ํ์ ๋ฏธํด๊ฒฐ ๋ฌธ์ ๊ฐ ์๋์ง ์๋ ์ฌ๋์ด ์์ต๋๊น? ํธ๋์ปค์์ ๊ด๋ จ ๋ฌธ์ ๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
@caesay Microsoft/TypeScript#15501 ์ฐธ์กฐ
์์ฑ์์์ ์ํ๋ฅผ ์ด๊ธฐํํด์ผ ํ์ง๋ง tslint๋ "์ํ๊ฐ ์ฝ๊ธฐ ์ ์ฉ์ ๋๋ค"๋ผ๊ณ ํ์ํฉ๋๋ค....
constructor(props) {
super(props);
this.state = {
value: props.defaultValue,
};
}
์ด๋ป๊ฒ ๊ณ ์น ์ ์๋์...........
setState ์ฌ์ฉ
setState๊ฐ ์์ฑ์์์ ์๋ํ์ง ์์ต๋๋ค
๋๋ componentWillMount w/setState๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
๊ฐ์ฌ ํด์
์๋ ํ์ธ์,
์ ์ฒด ์ค๋ ๋๋ฅผ ์ฝ์์ง๋ง @alanwei0 ์๋๋ฆฌ์ค๋ฅผ ์ฒ๋ฆฌํ ๊ณํ์ด ์๋์ง ํ์คํ์ง ์์ต๋๋ค.
state
๋ฅผ ReadOnly
๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ด๋ผ๋ ๋ฐ ์ ์ ์ผ๋ก ๋์ํฉ๋๋ค. ์์ฑ์์์ ์ด๊ธฐ ์ํ๋ฅผ ์ค์ ํ ์ ์๋ค๋ ๊ฒ์ componentDidMount
render
๊ฐ ํธ์ถ๋๊ธฐ ๋๋ฌธ์ ์๋นํ ๋ณต์กํฉ๋๋ค.
์์ฑ์์์ this.state = {
๋ฅผ ์ฌ์ฉํ๋ @pawelpabich ๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ์์ฑ์์์ readonly
๋ณ์์ ํ ๋นํ ์ ์์ผ๋ฉฐ Readonly<T>
๋ ํ ๋น์ ๋ฐฉ์งํ์ง ์์ต๋๋ค(์ ๋!).
interface TInterface {
test: string;
}
class TClass {
readonly blah: Readonly<TInterface>;
constructor() {
this.blah = { test: "constructor" };
}
fn = () => {
this.blah = { test: "fn" };
}
}
์ฌ๊ธฐ์ ์ ์ผํ ์ค๋ฅ๋ fn
๋ด๋ถ์ ์์ต๋๋ค. Readonly<T>
๋๋ฌธ์ด ์๋๋ผ readonly
ํค์๋ ๋๋ฌธ์
๋๋ค. ์ฌ์ค, ์ต์ ๋ฒ์ ์ ํ์ดํ์ readonly
ํค์๋๋ฅผ ์ฌ์ฉํ์ง๋ ์์ต๋๋ค. ๊ทธ๋์ state ๋ด๋ถ์ ์์ฑ์ ๋ณ๊ฒฝํ์ง ์๊ณ ์ค์ ๋ก state๋ฅผ ์๋ฌด๋ฐ๋ ํ ๋นํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๊ฐ ์ด์ผ๊ธฐํ ๋ฌธ์ ๋ ์์๋ ๊ตฌ์ฑ ์์์์ ์ํ ์์ฑ์ ์ ํ์ด ์์ค๋๋ ์ ํ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ์ ๋ฒ๊ทธ์์ต๋๋ค. ์ด๊ฒ์ ์ดํ๋ก ์์ ๋์์ผ๋ฉฐ, ๊ทธ๋ ๋ค๋ฉด ์ด ๋ฌธ์ ๋ฅผ ์ข ๋ฃํ ์ ์์ต๋๋ค.
@caesay ์ฃ์กํฉ๋๋ค, ์ ๋ ์ฐ๋ฆฌ๊ฐ ์ฌ๊ธฐ์ ๋งํ๋ ๊ฒฝ์ฐ๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ๋ด ๋ฌธ์ ๋ ๊ธฐ๋ณธ ํด๋์ค์์ ์ํ๋ฅผ ์ค์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ ๋ TS 2.4.1์ ์ฌ์ฉ ์ค์ ๋๋ค. ํน์ id๊ฐ ๋ฌธ์ ์ธ์ง ํ์ธํ ์ ์๋๋ก ํด์ฃผ์๋์?
ํญ์ setState(componentWillMount์์)๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
@pawelpabich ๋ค์ ๋งํ์ง๋ง ์ด๊ฒ์ ๋ฌธ์ ๊ฐ ์๋๋๋ค :) ์๋์ ์ผ๋ก ๊ธฐ๋ณธ ํด๋์ค์์ ์ํ๋ฅผ ํ ๋นํ ์ ์์ต๋๋ค. ์ด๋ป๊ฒ ํ ์ ์๋? ํ์ ๊ตฌ์ฑ ์์์์ ์ฌ์ฉ ์ค์ธ prop ๊ณ์ฝ์ ๋ชจ๋ฆ ๋๋ค.
interface BaseCompState {
baseState1?: string;
}
class BaseComp<TState extends BaseCompState> extends React.Component<any, TState> {
constructor(props) {
super(props);
this.state = {
baseState1: "fromBase",
};
}
}
interface TopCompState extends BaseCompState {
topState1?: string;
}
class TopComp extends BaseComp<TopCompState> {
constructor(props) {
super(props);
this.state = {
baseState1: "fromTop",
topState1: "fromTop",
};
}
}
์ด๊ฒ์ ํ์ ๊ตฌ์ฑ ์์์ ๊ฐ๋จํ ์์
๋๋ค(props๋ ์๋ต๋์์ง๋ง ๋์ผํ ์์ด๋์ด). ๊ธฐ๋ณธ ํด๋์ค์ this.state =
๋ TState
๊ฐ ๋ฌด์์ธ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ๋ถ๋ช
ํ ์๋ํ์ง ์์ต๋๋ค. ๊ฒ๋ค๊ฐ, ๊ทธ๊ฒ์ด _did_ ์๋ํ๋ค๋ฉด, ๊ทธ๊ฒ์ ๋จ์ง ๋ถ๋ชจ๊ฐ ์ค์ ํ ์ํ๋ฅผ ๋ฎ์ด์ฐ๊ฒ ๋ ๊ฒ์
๋๋ค. ์ต์ข
์ํ๋ { baseState1: "fronBase" }
์
๋๋ค. topState ์์ฑ์ ์ด๋ป๊ฒ ๋์๋์?
๊ธฐ๋ณธ ๊ตฌ์ฑ ์์์์ ์ํ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ค๊ณ ์ ๋์ ์ผ๋ก ํ์ ํ๋ ๊ฒฝ์ฐ ํ์ ๊ตฌ์ฑ ์์์ ์ํ๋ฅผ ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์ ์์ฑ์๋ก ์ ๋ฌํ ์ ์์ต๋๋ค(ํ ๋นํ ์ ์๋๋ก TState
๋ก). ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค. ์ด๊ฒ:
interface BaseCompState {
baseState1?: string;
}
class BaseComp<TState extends BaseCompState> extends React.Component<any, TState> {
constructor(props, state: TState) {
super(props);
this.state = Object.assign({
baseState1: "fromTop",
}, state);
}
}
interface TopCompState extends BaseCompState {
topState1?: string;
}
class TopComp extends BaseComp<TopCompState> {
constructor(props) {
super(props, {
topState1: "fromTop",
});
}
}
๋๋ ๋ ๊ฐ๋จํ๊ฒ ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์ ๋ด์์ this.setState(
๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค(์, ์์ฑ์์์ ํ ์ ์์ต๋๋ค!)
์ฌ๊ธฐ์๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
@caesay ์ ์ฝ ์กฐ๊ฑด์ด ์์ผ๋ฉด ํ ๋น์ด ์๋ฏธ๊ฐ ์๋ค๋ ๋ฐ ์ ์ ์ผ๋ก ๋์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ปดํ์ผ๋ฌ์ ์ฝ๋๊ฐ ์ฌ๋ฐ๋ฅธ์ง ํ์ธํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ์ ๋ณด๊ฐ ์์ง๋ง ๋ค์ ์ฝ๋๋ ์ฌ์ ํ ์ปดํ์ผ ์ค๋ฅ๋ฅผ ์์ฑํฉ๋๋ค.
import * as React from "react";
/* tslint:disable:max-classes-per-file*/
interface BaseProps {
baseProp: string;
}
interface BaseState {
baseState: string;
}
class Base<TProps extends BaseProps, TState extends BaseState> extends React.Component<TProps, TState> {
constructor(props) {
super(props);
this.state = {
baseState: props.baseProp
};
}
render() {
return <div>{this.state.baseState}</div>;
}
}
interface DerivedProps extends BaseProps {
derivedProp: string;
}
interface DerivedState extends BaseState {
derivedState: string;
}
export class Derived extends Base<DerivedProps, DerivedState> {
constructor(props) {
super(props);
this.state = {
derivedState: props.derivedProp
};
}
render() {
return <div>{this.state.derivedState}</div>;
}
}
์ค๋ฅ
webpack: Compiled successfully.
ERROR at Test.tsx(17,9):
TS2322: Type '{ baseState: any; }' is not assignable to type 'Readonly<TState>'.
ERROR at Test.tsx(39,9):
TS2322: Type '{ derivedState: any; }' is not assignable to type 'Readonly<DerivedState>'.
Property 'baseState' is missing in type '{ derivedState: any; }'.
Version: typescript 2.4.1
์ฒซ ๋ฒ์งธ. ์์ฑ์์ base์ ์๋ ์ํ์ด ์
๋ ฅ๋์ง ์์์ต๋๋ค. ๋ฐ๋ผ์ props.baseProp
๋ ํ ๋นํ ์ ์๋ any
์
๋๋ค!
๋์งธ, Derived
์ ์ํ์๋ ๋์ผํ ๋ฌธ์ ๊ฐ ์๊ณ baseState
๊ฐ ์์ต๋๋ค. ๋ฌผ๋ก Readonly์ ๊ด๊ณ์์ด ์๋ํ์ง ์์ต๋๋ค.
TProps extends BaseProps
์ฆ TProps
์๋ BaseProps
์ ๋์ผํ ๊ตฌ์ฑ์์ด ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์ ์๋์ง ์์ต๋๊น? ์ปดํ์ผ๋ฌ๊ฐ ๊ทธ๊ฒ์ ์ ์ถํ ์ ์์ ์๋ ์์ง๋ง ์ ์๋์ง ์์๋ค๊ณ ๋งํ๋ ๊ฒ์ ์ฌ๋ฐ๋ฅด์ง ์์ ๊ฒ ๊ฐ๋ค๋ ๊ฒ์ ์ดํดํฉ๋๋ค. Derived
์๋ ๊ฐ์ ์๊ฐ์ ์ ์ฉํ ์ ์์ต๋๋ค.
์์ฑ์์ @caesay setState
๋ ์ด ๋ฉ์๋๊ฐ ๋น๋๊ธฐ์์ด๊ณ ์ด๊ธฐ ์ํ ์ค์ ์์ด render
์ ๋๋ฌํ ์ ์๊ธฐ ๋๋ฌธ์ ์ ๋ขฐํ ์ ์๋ ์๋ฃจ์
์ด ์๋๋๋ค.
๋ด๊ฐ ๋ณผ ์์๋ ์ ์ผํ ์ ๋ขฐํ ์์๋ ์๋ฃจ์ ์ ํ์ ํด๋์ค์์ ์ ์ฒด ์ํ๋ฅผ ์ค์ ํ๋ ๊ฒ์ ๋๋ค. ์ฌ๊ธฐ์๋ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ฐฑํ ๋จ์ ์ด ์์ต๋๋ค.
์์์ ๋ณด์ฌ๋๋ฆฐ ์์ ๋ C#์์ ์๋ํ๋ฏ๋ก TypeScript์์ ์๋ํ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
componentWillMount
setState
๋ฅผ ํธ์ถํ๋ ๊ฒ์
๋๋ค. ๊ทํ์ ๊ธฐ์ง๋ ํด๋น ํ์ ์ํ์ ์์ด์ผ ํ๋ ํญ๋ชฉ์ ์์ง ๋ชปํ๋ฏ๋ก this.state
๋ฅผ ์์ ํ ๊ตฌ์ฑ์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ์ ํด๋์ค๋ ๋ถ๋ชจ์ componentWillMount
๋ฅผ ํธ์ถํ ๋ค์ ํ์ํ๋ค๊ณ ์๊ฐํ๋ ์ํ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.this.state
๋ฅผ ํ ๋นํ๋ ค๊ณ ํฉ๋๋ค.ํธ์ง๋จ, ์์ฑ์์ setState์ ๋ํด ์๋ชป๋์์์ ๋ฐ์ํ๊ณ ๊ฐ๋ ์ฑ์ ์ํด ๋ฐฑํฑ์ ์ถ๊ฐํฉ๋๋ค.
@ericanderson ์ ๋ ์ฐ๋ฆฌ๊ฐ ์ฌ๊ธฐ์ ์ด๋ค ์ง์ ๋ ์ด๋ฃจ์ง ๋ชปํ๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์์๋ฅผ ๋ณด์ฌ ๋๋ ธ๋๋ฐ ์ง์คํด ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ํ ๋ก ์ด ์ด๋ ต์ต๋๋ค.
Re setState
์์ฑ์์์ ์ฌ์ฉํ๋ ๊ฒ์ ์์ ํ์ง ์์ต๋๋ค . ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ง๋ง ๋ ๋๋ง์ด ๋ฐ์ํ๊ธฐ ์ ์ ์ํ๋ฅผ ์ค์ ํ์ง ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ ๋๋ฌธ์ ๊นจ์ง๋ ์ฝ๋๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ React ๋ฌธ์๋ ๊ฑฐ๊ธฐ์์ ์ฌ์ฉ๋์ด์๋ ์ ๋๋ค๋ ๊ฒ์ด ๋งค์ฐ ๋ถ๋ช
ํฉ๋๋ค.
@pawelpabich ์๋์, ์ด๊ฒ์ ์ด ์ฃผ์ฅ์ ํ ๊ณณ์ด ์๋๋๋ค. ๋น์ ์ ์ธ์ด์ ๋ํ ์ดํด๊ฐ ๊ทผ๋ณธ์ ์ผ๋ก ์๋ชป๋์์ต๋๋ค. ๊ทํ๊ฐ ์ ๊ณตํ ์์์ ๊ทํ๋ ์ฃผ์ ๋ํ ๊ทํ์ ํ ๋น ์ค ์ด๋ ์ชฝ์ด๋ "์ฃผ" ๊ณ์ฝ์ ์ถฉ์กฑํ์ง ์์์ต๋๋ค.
์๋ฅผ ๋ค์ด ํ ๋
this.state = { baseState: props.baseProp };
// now the state is exactly { baseState: props.baseProp }
์ํ๋ ์ ํํ { baseState: props.baseProp }
์ด๊ณ ์ด๊ฒ์ TProps extends BaseProps
์ ์๊ตฌ ์ฌํญ์ ์ถฉ์กฑํ์ง ์์ต๋๋ค(TProps๊ฐ ๋ฌด์์ธ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์! ์์ฑ์ด ์์ ์ ์์).
๊ทธ ํ, ๋น์ ์ _ SEPARATE _ ํ ๋น์ ํ๊ณ ์์ต๋๋ค.
this.state = { derivedState: props.derivedProp };
// now the state is exactly { derivedState: props.derivedProp }
์ํ๋ ์ด์ ์ ํํ { derivedState: props.derivedProp }
์ด๊ณ (๊ธฐ๋ณธ ์ํ ํ ๋น์ ๋ฎ์ด์ผ์ต๋๋ค!!) ์ด๊ฒ์ DerivedState ๋๋ BaseProps๋ฅผ ์ถฉ์กฑํ์ง ์์ต๋๋ค.
์ด๊ฒ์ด ์๋ํด์ผ ํ๋ค๊ณ ์๊ฐํ๋ ๊ฒ์ ์์ ํ ์๋ชป๋ ๊ฒ์ ๋๋ค. ๊ธฐ๋ณธ ๋ณ์ ํ ๋น์ด ์๋ํ๋ ๋ฐฉ์์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ ์ ๋ฌธ์ ์์ ์ธ์ด ๋์์ด๋์ ํจ๊ป ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฏ๋ก ์ฌ๊ธฐ์์ ์๋ฆผ์ ๋ฐ์ง ์๋๋ก ํ์ธ์.
์ฐธ๊ณ ๋ก ๊ธฐ๋ณธ render()
๋ฉ์๋๋ ์ฌ์ ์ํฉ๋๋ค. ์ฆ, ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์๋ ์๋ฌด ๊ฒ๋ ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ์ํ๋ ๊ฒ์ด๋ผ๊ณ ํ์ ํ๋ค๋ฉด ๋ณดํธ๋ ๋ฉค๋ฒ getBaseState()
๋ฅผ ์ถ๊ฐํ๊ณ ์ํ๋ฅผ ์ค์ ํ ๋ ํ์๋ ์์ฑ์์์ ์ด๊ฒ์ ํธ์ถํ ์ ์์ต๋๋ค(๋ฐ๋ผ์ ๊ธฐ๋ณธ ์ํ ๋
ผ๋ฆฌ๋ฅผ ๋ณต์ ํ ํ์๊ฐ ์์). ๊ทธ๋ฌ๋ ๋น์ ์ด ์ ๋ง๋ก ์ํ๋ ๊ฒ์ ํ์ ๊ตฌ์ฑ ์์๋ฅผ ์ ํ ์ฌ์ฉํ์ง ์๋ ๊ฒ์
๋๋ค. ๊ตฌ์ฑ์ ์ฌ์ฉํ๋๋ก ๊ตฌ์กฐ ์กฐ์ ์ ์๋ํฉ๋๋ค(์ฌ๋ฌ ํ์ ๊ฐ์ฒด๋ฅผ ํฌํจํ๋ ํ๋์ ๊ฐ์ฒด๊ฐ ์๋ ๊ฒฝ์ฐ). ํจ์ฌ ๊น๋ํด ์ง ๊ฒ ๊ฐ์์.
๋๋ ๋จ์ง ๋น์ ๊ณผ ์ด ๋ฌธ์ ์ ๋ํด ํ ๋ก ํ๊ธฐ ์ํด ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋ ์์์ ํ ๋ฐ์ง ๋ฌผ๋ฌ์๊ณ ์ถ์ง ์์ง๋ง, ์์...
๋๋ ์์ฑ์์์ setState
() ์ ๋ํด ์ ์ ํ ๊ฒ์ด์ง๋ง, componentWillMount
์์ ๊ทธ๊ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋ํ ๋๋์ ๋ณํ์ง ์์ต๋๋ค.
์ด ์์
์ ์ํํ๋ ๋ฐฉ๋ฒ์ ์ค์ ์:
https://github.com/ericanderson/set-state-example
ํนํ index.tsx:
import * as React from "react";
import * as ReactDOM from "react-dom";
/* tslint:disable:max-classes-per-file*/
interface BaseProps {
baseProp: string;
}
interface BaseState {
baseState: string;
}
class Base<TProps extends BaseProps, TState extends BaseState> extends React.Component<TProps, TState> {
public componentWillMount() {
this.setState({
baseState: this.props.baseProp,
});
}
public render() {
return (
<p>
<code>this.state.baseState: </code>
{this.state.baseState}
</p>
);
}
}
interface DerivedProps extends BaseProps {
derivedProp: string;
}
interface DerivedState extends BaseState {
derivedState: string;
}
export class Derived extends Base<DerivedProps, DerivedState> {
public componentWillMount() {
super.componentWillMount();
this.setState({
derivedState: this.props.derivedProp,
});
}
public render() {
return (
<div>
<p>
<code>this.state.derivedState: </code>
{this.state.derivedState}
</p>
{super.render()}
</div>
);
}
}
ReactDOM.render(<Derived derivedProp="its derived" baseProp="its basic" />, document.getElementById("main"));
@pawelpabich ์ด๊ธฐ ์ํ๋ก ๋คํ์ฑ ๊ตฌ์ฑ ์์๋ฅผ ๊ตฌํํ๋ ค๋ฉด ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์๋ฅผ ์ถ์ํํ๊ณ ํ์ ํด๋์ค์์ ๊ตฌํํ ์ถ์ getInitialState()
(๋๋ ์ ์ฌํ ํ
๋ง) ํจ์๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค. @ericanderson ์ด ๋ณด์ฌ์ค ๊ฒ์ฒ๋ผ ์์ฑ์์์ ๋๋ setState
๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ํ ๋ฒ๋ง ํ ๋นํ๋ ค๊ณ ํฉ๋๋ค.
์๋๋ ์ํ ๊ตฌ์ฑ๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๋ฅผ ์์ ํ ๋ถ๋ฆฌํ์ฌ ์์ ํ ๋คํ์ฑ ์๋ฃจ์ ์ผ๋ก ๋ณํํ ์์ ๋๋ค.
interface BaseProps {
baseProp: string;
}
interface BaseState {
baseState: string;
}
abstract class Base<TProps extends BaseProps, TState extends BaseState> extends React.Component<TProps, TState> {
constructor(props: TProps) {
super(props);
this.state = this.getInitialState();
}
protected abstract getInitialState(): TState;
protected getBaseState() {
return this.props.baseProp;
}
render() {
return <div>{this.state.baseState}</div>;
}
}
interface DerivedProps extends BaseProps {
derivedProp: string;
}
interface DerivedState extends BaseState {
derivedState: string;
}
export class Derived extends Base<DerivedProps, DerivedState> {
getInitialState(): DerivedState {
return {
baseState: this.getBaseState(),
derivedState: this.props.derivedProp,
};
}
render() {
return <div>{this.state.derivedState}</div>;
}
}
@patsisson ๊ฐ์ฌํฉ๋๋ค!
@caesay ๋๋ ๋ด๊ฐ ํ๋ ธ๋ค๋ ๊ฒ์ ์ธ์ ํ๊ณ ์ด๋ค ์ด์ ๋ก ํ ๋น์ด ์๋ก๋ฅผ ๋ฌด์ํ๋ ๊ฒ์ ๋ณด์ง ๋ชปํ์ต๋๋ค. CAPS์ !
๋ฅผ ์ฌ์ฉํด๋ ๋ฌธ์ ์์ ๋ฒ์ด๋ ์ ์์์ต๋๋ค.
@patsissons ์ @ericanderson ์ ๋ฌธ์ ์ ์ง์คํ๊ณ ์ด์ ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ฌ์ฉํ ์ ์๋ ์๋ฃจ์ ์ด ์์ต๋๋ค.
@pawelpabich ๋ด ๋งค๋๋ฆฌ์ฆ์ด ์ ๋ฌธ์ ์ด์ง ๋ชปํ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ํ์ง๋ง ๋ด๊ฐ ์ฌ๋ฌ ์ค๋ช , ์ํ ๋ฑ์ ์ ๊ณตํ๊ณ ๋น์ ์ด ๋ด ๋ง์ ๋ฃ์ง ์๊ธฐ๋ก ์ ํํ ๊ฒ์ ๊ณ ๋ คํ๋ฉด ์ดํดํ ๋งํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด ๋ถ๋ชจ๊ฐ ์ค์ ํ ์ํ๋ฅผ ๋ฎ์ด์ฐ๊ฒ ๋ฉ๋๋ค.
[_ํ๊ณ ์ถ์ ๊ฒฝ์ฐ_] ๊ธฐ๋ณธ โโ๊ตฌ์ฑ ์์์ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด ํ์ ๊ตฌ์ฑ ์์์ ์ํ๋ฅผ ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์ ์์ฑ์๋ก ์ ๋ฌํ ์ ์์ต๋๋ค.
[_ํ์๋ ๊ตฌ์ฑ ์์์ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ ๊ฒฝ์ฐ_] ๋ณดํธ๋ ๋ฉค๋ฒ getBaseState()๋ฅผ ์ถ๊ฐํ๊ณ ์ํ๋ฅผ ์ค์ ํ ๋ ํ์๋ ์์ฑ์์์ ์ด๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
@patsisson ์ด ํ ์ผ์ ์ฌ๊ธฐ์ ์ด๋ฏธ ์ธ๊ธ๋ ์ฃผ์์ ๊ฐ์ ธ์์ ์ฝ๋ ์ํ์ ์ ๊ณตํ๋ ๊ฒ์ด์์ต๋๋ค. ์ด๋ ํ์ํ์ง ์์์ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ stackoverflow๊ฐ ์๋๋ฉฐ ์ฐ๋ฆฌ๋ ์ข ์ข ๊ฑฐ๊ธฐ์์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ง ์ฝ๋ ์ํ์ ์ ๊ณตํ์ง ์์ต๋๋ค.
๋๋ ๋ฐ์ ๋ฐ typescript์ ์ต์ํ์ง ์์ผ๋ฉฐ ์๋ง๋ sth๋ฅผ ๋ชจ๋ฅด์ง๋ง ์ฑ์ด ์ค๋ฅ, ๊ฒฝ๊ณ ๋ฐ ํํธ ์์ด ์ปดํ์ผ๋์ง๋ง ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ์๋๋ ์์ ์ปดํฌ๋ํธ์
๋๋ค. Readonly
์ํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. Readonly
๋ณ๊ฒฝ ์ ์ ์ฑ์ด ์๋ํ๋ค๋ฉด ์ด ๋ณ๊ฒฝ ํ์๋ ์๋์ด ์ค์ง๋๊ณ ์ปดํ์ผ ์๊ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.
import * as React from 'react';
export default class HomePage extends React.Component<any, Map<string, string>> {
public componentWillMount() {
const map = new Map<string, string>();
map.set('aKey', 'aValue');
this.setState(map);
}
public render() {
return (
<div className="home">
<div className="greeting">
Home page: {this.state.get('aKey')} // <-- I get an error here
</div>
</div>
);
}
}
์ค๋ฅ:
homePage.tsx:12 Uncaught TypeError: this.state.get is not a function
at HomePage.render (homePage.tsx:12)
at eval (ReactCompositeComponent.js:793)
at measureLifeCyclePerf (ReactCompositeComponent.js:73)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (
์ํ๋ ํญ์ ์ผ๋ฐ ํค ๊ฐ์ฒด์ฌ์ผ ํ๋ฏ๋ก ๋์ ์ํ๋ฅผ ์ ์ํ์ญ์์ค.
{ values: Map <string, string> }
์ ๊ฐ์ด ์ฝ๊ณ
this.state.values.get('aKey')
Op vr 29 9์ 29์ผ 2017 om 09:01 schreef Janusz Biaลobrzewski <
์๋ฆผ@github.com>:
๋๋ ๋ฐ์ํ๊ณ ํ์ดํํ๋ ๊ฒ์ด ์ฒ์์ด๊ณ ์๋ง๋ sth๋ฅผ ๋ชจ๋ฅด์ง๋ง ์ฌ์ง์ด
์ฑ์ด ์ค๋ฅ, ๊ฒฝ๊ณ ๋ฐ ํํธ ์์ด ์ปดํ์ผ๋์ง๋ง ๋ฐํ์์ด ํ์๋ฉ๋๋ค.
์ค๋ฅ. ์๋๋ ์์ ์ปดํฌ๋ํธ์ ๋๋ค. ๋๋ ์ค๋ฅ๋ฅผ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋๋ฆฝ๋๋ค.
์ํ. ์ฑ์ด ์ฝ๊ธฐ ์ ์ฉ ๋ณ๊ฒฝ ์ด์ ์ ์๋ํ๋ค๋ฉด ์ด ํ์
๋ณ๊ฒฝํ๋ฉด ์๋์ด ์ค์ง๋๊ณ ์ปดํ์ผ ์๊ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.* 'react'์์ React๋ก ๊ฐ์ ธ์ค๊ธฐ;
๋ด๋ณด๋ด๊ธฐ ๊ธฐ๋ณธ ํด๋์ค HomePage๋ React.Component๋ฅผ ํ์ฅํฉ๋๋ค.> { ๊ณต๊ฐ componentWillMount() {
const ๋งต = ์ ๋งต();
map.set('aKey', 'aValue');
this.setState(์ง๋);
}๊ณต๊ฐ ๋ ๋() {
return ( <div className="home"> <div className="greeting"> Home page: {this.state.get('aKey')} // <-- I get an error here </div> </div> );
}
}์ค๋ฅ:
ํํ์ด์ง. tsx:12 ์กํ์ง ์์ TypeError: this.state.get์ ํจ์๊ฐ ์๋๋๋ค.
HomePage.render์์(homePage.tsx:12)
ํ๊ฐ ์(ReactCompositeComponent.js:793)
measureLifeCyclePerf์์ (ReactCompositeComponent.js:73)
ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext์์ (โ
๋น์ ์ด ์ธ๊ธ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14250#issuecomment-333047367 ,
๋๋ ์ค๋ ๋ ์์๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ABvGhM5hDyRNyUeZuIiGeTZk1N-rfuA4ks5snJW5gaJpZM4LuDWV
.
๊ฐ์ฌํฉ๋๋ค. ํ์ง๋ง state๋ฅผ Readonly<S>
๋ก ์ ์ธํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ค์ฒฉ๋ ๋ฉค๋ฒ๋ Readonly์ ์ํฅ์ ๋ฐ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
์ธ์ ๊ฐ๋ Readonly
๊ฐ ์ฌ๊ท์ ์ผ๋ก ์ ์ฉ๋ ์ ์์ง๋ง ์ง๊ธ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋์ง ํ์ธํ๋ ๊ฒ์ ์ฌ์ฉ์์ ๋ชซ์
๋๋ค. ๊ทํ์ ๊ฒฝ์ฐ ์ค์ ๋ก ReadonlyMap
๋๋
interface State {
readonly [key: string]: string;
}
๋๋ ์ค์ฒฉ:
interface State {
map: { readonly [key: string]: string };
}
๊น์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
export type DeepReadonly<T> =
T extends Array<any> ?
ReadonlyArray<T[0]> :
T extends Date ?
T :
T extends Function ?
T :
T extends object ?
{ readonly [P in keyof T]: DeepReadonly<T[P]> } :
T;
export type Writable<T> =
T extends ReadonlyArray<any> ?
Array<WritableObject<T[0]>> :
T extends Array<any> ?
Array<WritableObject<T[0]>> :
WritableObject<T>;
type WritableObject<T> =
T extends Date ?
T :
T extends Function ?
T :
T extends object ?
{ -readonly [P in keyof T]: Writable<T[P]> } :
T;
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋ฌธ์ 3์ ๋ ผ์์ ์ฌ์ง๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
React์์ ์์ ์๋ฅผ _๊ธฐ์ ์ ์ผ๋ก_ ํ ์ ์๋ค๋ ๊ฒ์ ์ณ์ง๋ง, ๋๋ ๊ทธ๊ฒ์ด React๊ฐ ์ฌ์ฉ๋๋๋ก ์๋๋ ๋ฐฉ์์ด ์๋๋ผ๊ณ ํ์คํ ์ฃผ์ฅํ๊ณ ์ถ์ต๋๋ค.
์ด๊ฒ์ 3๊ฐ์ง ๋ณ๊ฐ์ ๊ฒฝ์ฐ๋ก ๋๋ ์ ์์ต๋๋ค.
์ผ๋ฐ ์ด๊ธฐํ
props ๊ธฐ๋ฐ ์ด๊ธฐํ
forceUpdate
๋ก ๋ฌด์์ ํ ๋น์ฌ๋๋ค์ "์ฌ๋ฐ๋ฅธ" ๋ฐฉํฅ์ผ๋ก ๋ฐ์ด๋ถ์ด๋ ๊ฒ์ด ๋ ๋ซ๋ค๊ณ ์๊ฐํ๋ฉด
public state
๋ฅผ ๋ค์ ์ ์ธํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.