From b82af166100fa455cff8fa4f97f3950570e0aaeb Mon Sep 17 00:00:00 2001 From: daishi Date: Mon, 16 Oct 2023 19:29:25 +0900 Subject: [PATCH 1/2] docs: prefer object getters to derive util --- docs/guides/computed-properties.mdx | 63 +++++++++++++++++------------ readme.md | 27 ++++--------- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/docs/guides/computed-properties.mdx b/docs/guides/computed-properties.mdx index 439a0b3c..b2dc0ca5 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,43 @@ 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` or `watch`. + +```js +const user = proxy({ + name: 'John', +}) +const greetings = proxy({ + greetingEn: 'Hello ' + user.name, +}) +const unsub = subscribe(user, () => { + greetings.greetingEn = 'Hello ' + 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 From 39dabf0a392229576a361adaed8de382eebb8ddb Mon Sep 17 00:00:00 2001 From: daishi Date: Tue, 17 Oct 2023 11:15:57 +0900 Subject: [PATCH 2/2] watch example --- docs/guides/computed-properties.mdx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/guides/computed-properties.mdx b/docs/guides/computed-properties.mdx index b2dc0ca5..e4b07fca 100644 --- a/docs/guides/computed-properties.mdx +++ b/docs/guides/computed-properties.mdx @@ -102,7 +102,7 @@ const greetings = proxy({ ``` Another method would be to create a separate proxy and -synchronize with `subscribe` or `watch`. +synchronize with `subscribe`. ```js const user = proxy({ @@ -111,11 +111,23 @@ const user = proxy({ const greetings = proxy({ greetingEn: 'Hello ' + user.name, }) -const unsub = subscribe(user, () => { +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: