diff --git a/docs/guides/computed-properties.mdx b/docs/guides/computed-properties.mdx index 439a0b3c..e4b07fca 100644 --- a/docs/guides/computed-properties.mdx +++ b/docs/guides/computed-properties.mdx @@ -16,8 +16,7 @@ In Valtio you can use object & class getters and setters to create computed prop const state = proxy({ count: 1, get doubled() { - // We recommend `state.count` for clarity to beginners, but `this.count` works too - return state.count * 2 + return this.count * 2 }, }) console.log(state.doubled) // 2 @@ -41,13 +40,9 @@ However, when you make a snapshot, calls to `snap.doubled` are effectively cache ```js const user = proxy({ name: 'John', - // OK - can reference sibling props via the proxy object + // OK - can reference sibling props via `this` get greetingEn() { - return 'Hello ' + user.name - }, - // OK - or via `this` - get greetingFr() { - return 'Bonjour ' + this.name + return 'Hello ' + this.name }, }) ``` @@ -57,13 +52,9 @@ const state = proxy({ // could be nested user: { name: 'John', - // OK - can reference sibling props via the proxy object + // OK - can reference sibling props via `this` get greetingEn() { - return 'Hello ' + state.user.name - }, - // OK - or via `this` - get greetingFr() { - return 'Bonjour ' + this.name + return 'Hello ' + this.name }, }, }) @@ -75,13 +66,9 @@ const state = proxy({ name: 'John', }, greetings: { - // WRONG - can reference sibling props only. Use `derive` instead + // WRONG - `this` points to `state.greetings`. get greetingEn() { - return 'Hello ' + state.user.name - }, - // WRONG - `this` points to `state.greetings`. Use `derive` instead - get greetingFr() { - return 'Bonjour ' + this.user.name + return 'Hello ' + this.user.name }, }, }) @@ -92,17 +79,55 @@ const user = proxy({ name: 'John', }) const greetings = proxy({ - // WRONG - can reference sibling props only. Use `derive` instead + // WRONG - `this` points to `greetings`. get greetingEn() { - return 'Hello ' + user.name + return 'Hello ' + this.name }, - // WRONG - `this` points to `greetings`. Use `derive` instead - get greetingFr() { - return 'Bonjour ' + 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: diff --git a/readme.md b/readme.md index 577e2ba5..d07a2572 100644 --- a/readme.md +++ b/readme.md @@ -292,33 +292,22 @@ const Component = () => { } ``` -#### `derive` util +#### Computed properties -You can subscribe to some proxies and create a derived proxy. +You can define computed properties with object getters. ```js -import { derive } from 'valtio/utils' - -// create a base proxy const state = proxy({ count: 1, + get doubled() { + return this.count * 2 + }, }) +``` -// create a derived proxy -const derived = derive({ - doubled: (get) => get(state).count * 2, -}) +Consider it as an advanced usage, because the behavior of `this` is sometimes confusing. -// alternatively, attach derived properties to an existing proxy -derive( - { - tripled: (get) => get(state).count * 3, - }, - { - proxy: state, - } -) -``` +For more information, check out [this guide](./docs/guides/computed-properties.mdx). #### `proxyWithHistory` util