이번 포스팅에서는 Props에 대해 알아보려고 한다.
부모 컴포넌트에서 자식 컴포넌트로 전달되는 데이터들을
Properties(이하 Props)
라고 한다.
앞선 포스팅에서 속성(Attribute)에 대해 살펴보았다. 속성과 Props의 개념은 동일하다. 다만 HTML 태그에서 사용하면 속성
, 컴포넌트에서 사용하면 Props
라고 한다. 용어 차이만 있을 뿐!
<script>
import Component from './Component.svelte';
</script>
<div class="this-is-attribute"></div> <!-- class는 속성이다. -->
<Component text="this-is-property" /> <!-- text는 Props이다. -->
(출처 - Joy of Code)
Props는 기본적으로 단방향 데이터 흐름으로 이루어진다. 단방향 데이터 흐름은 부모에서 자식 컴포넌트로 데이터가 전달되는 것을 말한다. 반대로 자식에서 부모 컴포넌트로 데이터를 전달하기 위해서는 이벤트를 통해야 한다.
자식 컴포넌트에서 Props의 값을 변경하더라도 부모 컴포넌트에서는 Props로 전달한 값은 업데이트되지 않는다. 단방향 데이터 흐름은 데이터 흐름을 단순하게 만들고, 흐름이 이해하기 쉽기 때문에 개발과 유지보수가 편리하다.
만약 Props를 양방향 데이터 흐름으로 사용하려면 데이터 바인딩을 하면 되는데, 이는 나중에 다시 알아보도록 하자. 🤔
<script>
import Child from './Child.svelte';
</script>
<Child text="hello, world!"/>
<!-- src/Child.svelte -->
<script>
export let text;
</script>
<p>{text}</p>
위처럼 export를 사용하여 Props를 전달받을 수 있다.
<!-- src/Child.svelte -->
<script>
export let text = '전달받은 값이 없습니다.';
</script>
<p>{text}</p>
자식 컴포넌트에 Props 값이 전달되지 않았을 경우를 대비하여 Props의 기본값을 설정할 수 있다.
전개 연산자(Spread Operator)는 많은 양의 Props를 자식 컴포넌트에 전달해야 할 때 코드 양을 줄이는 역할을 한다.
<!-- src/Info.svelte -->
<script>
export let name;
export let version;
export let speed;
export let website;
</script>
<p>
The <code>{name}</code> package is {speed} fast.
Download version {version} from <a href="https://www.npmjs.com/package/{name}">npm</a>
and <a href={website}>learn more here</a>
</p>
<script>
import Info from './Info.svelte';
const pkg = {
name: 'svelte',
version: 3,
speed: 'blazing',
website: 'https://svelte.dev'
};
</script>
<Info
name={pkg.name}
version={pkg.version}
speed={pkg.speed}
website={pkg.website}
/>
코드가 너무 길다.... 전개 연산자를 사용하면 아래와 같이 코드 양을 줄일 수 있다.
<script>
import Info from './Info.svelte';
const pkg = {
name: 'svelte',
version: 3,
speed: 'blazing',
website: 'https://svelte.dev'
};
</script>
<Info {...pkg}/>
아주 코드가 간단해졌다. 😎
스벨트는 Props를 전달받은 컴포넌트에서 export로 Props를 선언하지 않아도 Props를 사용할 수 있는 방법을 제공한다. 최적화하기 어렵기 때문에 이 방법은 추천하지 않지만, 어떤 Props가 컴포넌트로 전달될지 모르는 경우에는 유용하게 사용 가능하다.
<!-- src/Info.svelte -->
<p>
The <code>{$$props.name}</code> package is {$$props.speed} fast.
Download version {$$props.version} from <a href="https://www.npmjs.com/package/{$$props.name}">npm</a>
and <a href={$$props.website}>learn more here</a>
</p>
$$props
변수는 컴포넌트로 전달된 모든 Props를 담고 있다.
<!-- src/Info.svelte -->
<script>
export let name;
export let version;
</script>
<p>
The <code>{name}</code> package is {$$restProps.speed} fast.
Download version {version} from <a href="https://www.npmjs.com/package/{$$restProps.name}">npm</a>
and <a href={$$restProps.website}>learn more here</a>
</p>
$$restProps
변수는 export로 정의되지 않은 Props만 담고 있다. name과 version Props는 export로 선언되었기 때문에 $$restProps.name
과 $$restProps.version
의 값은 undefined다.
사용자 지정 CSS 속성을 컴포넌트 Props로 전달할 수 있다. ---style-props는 문법적 설탕(Syntactic sugar)이다.
<!-- public/global.css -->
html {
---theme-color: black;
}
<!-- src/StyleProps.svelte -->
<div>테마 적용</div>
<style>
div {
color: var(--theme-color);
}
</style>
<!-- src/App.svelte -->
<script>
import StyleProps from './StyleProps.svelte';
</script>
<StyleProps --theme-color="red" />
<StyleProps />
"--theme-color='red'"를 전달하고 나머지 하나에는 아무것도 전달하지 않았다. --theme-color를 전달한 StyleProps 컴포넌트의 글씨는 빨간색, 전달하지 않은 StyleProps는 검은색으로 나타난다.