Props up with Svelte
Tags: svelte, react, webdev, javascript
Published: 2019-10-07 17:19:06

## Passing props down (React)

Let's present the paradigm by creating a small **Counter** component in [React](https://reactjs.org/) first:

```jsx
export default function Counter() {
  const [count, setCount] = useState(0);
  const incr = () => setCount(c => c + 1);
  return (
    <div>
      <div>{count}</div>
      <button onClick={incr}>+1</button>
    </div>
  );
}

```

And let's use it an **App** component:

```javascript
import './Counter';

function App() {
  return ( 
    <Counter />
  )
}

```
Now, let us imagine that we need to know **if the count is more than 1** in our `App` component (maybe we need to pluralize a string if that's the case).

Mmh... we don't have access to `count` from `App`. We have to [lift the state up](https://reactjs.org/docs/lifting-state-up.html) and pass it back down as a prop to `<Counter />`. As a result, we also need to pass down the increment function to update said `count`. Here is an implementation:


```jsx

// App.js

import Counter from './Counter';

function App() {
  // state is now in the parent
  const [count, setCount] = useState(0);
  const incr = () => setCount(c => c + 1);
  return <Counter count={count} incr={incr} />;
}

```

```jsx

// Counter.js

export default function Counter(props) {
  // the child uses props
  const { count, incr } = props;
  return (
    <div>
      <div>{count}</div>
      <button onClick={incr}>+1</button>
    </div>
  );
}

```
Nice, it works ([sandbox](https://codesandbox.io/embed/lifting-state-up-mynfw)). Yet it's slightly odd to me that our `Counter `component has become a shell of itself (it seems). It doesn't do any counting anymore. It wires in a click handler. Maybe we'd have to rename it? But I digress.

## Component Bindings (Svelte)

Let's try to handle the same issue in [Svelte](https://svelte.dev/). Here is our `Counter`:

```html
<script>
  let count = 0;
  const incr = () => (count = count + 1);
</script>

<div>{count}</div>
<button on:click={incr}>+1</button>

```
And a parent component, `App`:

```html
<script>
   import Counter from './Counter.svelte';
</script>

<Counter />
```

So we're back in the same situation: we want to use `count` from `Counter` in the `App` component. We *could* lift state up again as before. But this time, we can actually **pass props up** without having to re-wire any state. We need to:

1/ `export` the variable in the `Counter` (child) component:

```javascript
export let count = 0
```

2/ bind to the component value in the `App` (parent) component

```html
<script>
  let count;
</script>
< Counter bind:count />
```

We declare the variable in the `script` tag, and we grab it via [component bindings](https://svelte.dev/examples#component-bindings) (`bind:count`). So, we have access to the count in the parent component! Let's actually solve the problem in full, using [reactive declarations](https://svelte.dev/docs#3_$_marks_a_statement_as_reactive) as well.

`App.svelte`:

```html
<script>
  import Counter from './Counter.svelte';
  let count;
  $: isMoreThan1 = count > 1;
</script>

<Counter bind:count />
<span>is More than 1: {isMoreThan1} </span>

```

`Counter.svelte`:

```html
<script>
  export let count = 0;
  const incr = () => (count = count + 1);
</script>

<div>{count}</div>

<button on:click={incr}>
  +1
</button>

```

[View it in the REPL](https://svelte.dev/repl/b4a321999c7a4894ac04aa325bfed2c0?version=3.12.1).

I'm interested in your thoughts. What do you think are the repercussion for componentization in Svelte coming from React? Is there a similar mechanism in Vue or Angular? 

Give me a follow [on Twitter](https://twitter.com/collardeau) for more explorations with Svelte :)