add warning in dev, add docs

pull/15589/head
ComputerGuy 5 months ago
parent 610420561c
commit 967ccc5d86

@ -65,6 +65,19 @@ let { done, text } = todos[0];
todos[0].done = !todos[0].done;
```
You can also use `$state` in return statements to proxy their argument:
```js
function createCounter() {
return $state({
count: 0,
increment() {
this.count++;
}
});
}
```
### Classes
You can also use `$state` in class fields (whether public or private):

@ -219,6 +219,12 @@ Reactive `$state(...)` proxies and the values they proxy have different identiti
To resolve this, ensure you're comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a state proxy.
### state_return_not_proxyable
```
The argument passed to a `$state` in a return statement must be a plain object or array. Otherwise, the `$state` call will have no effect
```
### transition_slide_display
```

@ -185,6 +185,10 @@ To fix it, either create callback props to communicate changes, or mark `person`
To resolve this, ensure you're comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a state proxy.
## state_return_not_proxyable
> The argument passed to a `$state` call in a return statement must be a plain object or array. Otherwise, the `$state` call will have no effect
## transition_slide_display
> The `slide` transition does not work correctly for elements with `display: %value%`

@ -40,16 +40,11 @@ export function CallExpression(node, context) {
parent?.type === 'ReturnStatement' ||
(parent?.type === 'ArrowFunctionExpression' && parent.body === node)
) {
if (
node.arguments[0] &&
should_proxy(
/** @type {Expression} */ (context.visit(node.arguments[0])),
context.state.scope
)
) {
return b.call('$.proxy', node.arguments[0]);
} else {
return node.arguments[0] ?? b.void0;
if (node.arguments[0]) {
return b.call(
'$.return_proxy',
/** @type {Expression} */ (context.visit(node.arguments[0] ?? b.void0))
);
}
}
}

@ -12,6 +12,7 @@ import { state as source, set } from './reactivity/sources.js';
import { STATE_SYMBOL } from '#client/constants';
import { UNINITIALIZED } from '../../constants.js';
import * as e from './errors.js';
import * as w from './warnings.js';
import { get_stack } from './dev/tracing.js';
import { tracing_mode_flag } from '../flags/index.js';
@ -282,6 +283,21 @@ export function proxy(value) {
});
}
/**
* @template T
* @param {T} value
* @param {Source<T>} [prev]
* @returns {T | void}
*/
export function return_proxy(value, prev) {
const res = proxy(value, prev);
if (res !== value || (typeof value === 'object' && value !== null && STATE_SYMBOL in value)) {
// if the argument passed was already a proxy, we don't warn
return res;
}
w.state_return_not_proxyable();
}
/**
* @param {Source<number>} signal
* @param {1 | -1} [d]

@ -170,6 +170,17 @@ export function state_proxy_equality_mismatch(operator) {
}
}
/**
* The argument passed to a `$state` in a return statement must be a plain object or array. Otherwise, the `$state` call will have no effect
*/
export function state_return_not_proxyable() {
if (DEV) {
console.warn(`%c[svelte] state_return_not_proxyable\n%cThe argument passed to a \`$state\` in a return statement must be a plain object or array. Otherwise, the \`$state\` call will have no effect\nhttps://svelte.dev/e/state_return_not_proxyable`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/state_return_not_proxyable`);
}
}
/**
* The `slide` transition does not work correctly for elements with `display: %value%`
* @param {string} value

@ -2,7 +2,7 @@
import * as $ from 'svelte/internal/client';
export default function proxy(object) {
return $.proxy(object);
return $.return_proxy(object);
}
export function createCounter() {
@ -11,4 +11,4 @@ export function createCounter() {
$.update(count);
}
export const proxy_in_arrow = (object) => $.proxy(object);
export const proxy_in_arrow = (object) => $.return_proxy(object);
Loading…
Cancel
Save