---
title: 'Computed Properties'
section: 'Advanced'
description: 'Use object getters and setters'
---
# Computed Properties
In Valtio you can use object & class getters and setters to create computed properties.
ℹ️ Note
Getters in JavaScript are a more advanced feature of the language, so Valtio recommends using them with caution. That said, if you are a more advanced JavaScript programmer, they should work as you expect; see the "Note about using `this`" section below.
## Simple object getter
```js
const state = proxy({
count: 1,
get doubled() {
return this.count * 2
},
})
console.log(state.doubled) // 2
// Getter calls on the snapshot work as expected
const snap = snapshot(state)
console.log(snap.doubled) // 2
// When count changes in the state proxy
state.count = 10
// Then snapshot's computed property does not change
console.log(snap.doubled) // 2
```
When you call `state.doubled` on the `state` proxy, it is not cached, and will be re-calculated on every call (if you must cache this result, see the section below on `proxy-memoize`).
However, when you make a snapshot, calls to `snap.doubled` are effectively cached, because the value of an object getter is copied during the snapshot process.
ℹ️ Note
In the current implementation a computed property should only reference \*\*\_sibling\*\*\* properties, otherwise you'll encounter weird bugs. For example:
```js
const user = proxy({
name: 'John',
// OK - can reference sibling props via `this`
get greetingEn() {
return 'Hello ' + this.name
},
})
```
```js
const state = proxy({
// could be nested
user: {
name: 'John',
// OK - can reference sibling props via `this`
get greetingEn() {
return 'Hello ' + this.name
},
},
})
```
```js
const state = proxy({
user: {
name: 'John',
},
greetings: {
// WRONG - `this` points to `state.greetings`.
get greetingEn() {
return 'Hello ' + this.user.name
},
},
})
```
```js
const user = proxy({
name: 'John',
})
const greetings = proxy({
// WRONG - `this` points to `greetings`.
get greetingEn() {
return 'Hello ' + this.name
},
})
```
A workaround to it is to attach the related object as a property.
```js
const user = proxy({
name: 'John',
})
const greetings = proxy({
user, // attach the `user` proxy object
// OK - can reference user props via `this`
get greetingEn() {
return 'Hello ' + this.user.name
},
})
```
Another method would be to create a separate proxy and
synchronize with `subscribe`.
```js
const user = proxy({
name: 'John',
})
const greetings = proxy({
greetingEn: 'Hello ' + user.name,
})
subscribe(user, () => {
greetings.greetingEn = 'Hello ' + user.name
})
```
Or with `watch`.
```js
const user = proxy({
name: 'John',
})
const greetings = proxy({})
watch((get) => {
greetings.greetingEn = 'Hello ' + get(user).name
})
```
## Object getter and setter
Setters are also supported:
```js
const state = proxy({
count: 1,
get doubled() {
return state.count * 2
},
set doubled(newValue) {
state.count = newValue / 2
},
})
// Setter calls on the state work as expected
state.doubled = 4
console.log(state.count) // 2
// Getter calls on the snapshot work as expected
const snap = snapshot(state)
console.log(snap.doubled) // 4
// And setter calls on the snapshot fail as expected
// compile error: Cannot assign to 'doubled' because it is a read-only property.
// runtime error: TypeError: Cannot assign to read only property 'doubled' of object '#