# Syntax Introduction: A Simple Counter

To understand the structure and syntax of using `defineState` to build a state manager, let's start with a simple but functional example. This example implements a counter state manager. It allows you to create the counter, increment the counter, and get the current counter value.

```javascript
// c/simpleCounter/counterManager.js
import { defineState } from "@lwc/state";

// Use the `defineState` function to define the values
// and actions your state manager provides
const counterManager = defineState(
  // This anonymous JavaScript function is the implementation
  // for a state manager.
  // `atom`, `computed`, and `setAtom` are state management functions
  // available in the context of `defineState`.

  // Your state manager can accept any number of arguments to define
  // its initial state. Here, this state manager can accept one argument
  // `initialValue` to set the beginning counter value, or use a
  // default value of zero.
  ({ atom, computed, setAtom }, initialValue = 0) => {
    // Create the counter, the state for this state manager.
    // An `atom` represents a single, reactive piece of data.
    // Changes to an atom trigger updates in components or
    // re-computation of derived values.
    const count = atom(initialValue);

    // Create an action to modify the state by incrementing it
    const increment = () => {
      setAtom(count, count.value + 1);
    };

    // Return an object that defines the public API of counterManager
    return {
      count,
      increment,
    };
  },
);
export default counterManager;
```

A state manager like `counterManager` is a function that creates instances of the state manager. Arguments you pass to the state manager function are available to the state manager instance as parameters when it initializes. Each state manager instance has its own set of values. Use values and actions from the state manager instance in your component template and JavaScript.

For example, to use the `counterManager` state manager in a component, save the result of calling it. Then access state manager values and actions through the saved reference.

```javascript
// c/simpleCounter/simpleCounter.js
import { LightningElement } from "lwc";
import counterManager from "./counterManager";

export default class SimpleCounter extends LightningElement {
  counter = counterManager(100);

  // Create an action handler that uses the counterManager `increment` action
  handleIncrement() {
    this.counter.value.increment();
  }
}
```

```html
<!-- c/simpleCounter/simpleCounter.html -->
<template>
  <lightning-card title="Example: Simple Counter">
    <section class="slds-p-around_small">
      <p>Count: {counter.value.count}</p>
    </section>

    <section class="slds-p-around_small">
      <lightning-button label="Increment" onclick={handleIncrement}></lightning-button>
    </section>
  </lightning-card>
</template>
```

## Understand the `counterManager` Example

Even this simple example uses some advanced JavaScript features. Let's break down the syntax a little bit at a time, to try to clarify the specifics.

- `defineState((...) => { ... })`: The `defineState` function takes a single argument: a callback function. The callback function is the `{ ... }` part, which we expand on in a moment.

- `({ atom, computed, setAtom }, initialValue = 0)`: The callback function defines the state manager. The function *is* your state manager. The function can accept an arbitrary number of parameters, which you can use for setting the initial state.

  - The first argument passed to the function is an object containing the state primitives: `atom`, `computed`, and `setAtom`. Your state manager uses these primitives to define and change the values that it exposes.
  - After that object, your state manager can accept one or more parameters — here `initialValue` — to configure the state manager instance. You can define parameters and default values as you would for any other JavaScript function.

<!---->

- `const count = atom(initialValue)`: Inside the state manager, define your state. Here, `atom()` creates a reactive variable named `count`. The value of `count` is the only state managed in this example.

- `const increment = () => { ... }`: This is an action, which will be part of this state manager's public interface. It's just a function that encapsulates the logic for changing the state. Actions are the only way consumers of your state manager can change its internal state.

- `setAtom(count, ...)`: Within the `increment` action, and anywhere else you need to modify state, use the `setAtom` primitive. This ensures that, when your state changes, LWC's reactivity system is notified of that change.

- `return { count, increment }`: Your state manager completes when it returns an object that defines the public API for your state manager instance. Components can access `<instance>.value.count` to read the state and `<instance>.value.increment()` to call the action.

## Atom Data Types

The `atom()` function creates a reactive "atomic" value, which is essentially a wrapper around a piece of data that LWC can use to make components and other state managers reactive to changes in that data. An atom can be a simple value, like a number, or it can be a more complex value, like an object or array.

:::note
You can wrap any JavaScript value, but it's recommended to stick to JSON-serializable values or `undefined` for best compatibility.
:::

## Next Steps

If this is your first time using JavaScript with this structure, read through it a few times. It's not easy to understand the first time, or even the second.

To cement your understanding, start with this example and modify it, perhaps to add a second simple action, like `double`. Take it even further, and turn it into a game leveling manager. Your state manager should track and increment a second atom, `currentLevel` when certain incremental thresholds of `count` are reached. Allow the threshold to be set from an argument provided when an instance is created, and reset `count` whenever you level up. Give it a go, and see how much you learn!
