Svelte 5의 새로운 $state를 보자마자 다음을 수행하고 싶은 유혹을 느낄 수 있습니다.
// sharedState.svelte.js export const searchState = $state(""); // This won't work!
<!-- App.svelte --> <script> import { searchState } from './sharedState.svelte.js' function handleClick(){ // This won't work! searchState = "bicycles"; } </script <button onclick={handleClick}>Search for bicycles</button>
이 방법은 작동하지 않습니다. 이유는 다음과 같습니다.
Svelte 5의 가장 복잡한 부분에 직면하게 됩니다. 반응성이 작동하는 방식과 컴파일러가 반응성을 숨기는 방법입니다.
숫자나 문자열과 같은 단일 값을 내보낼 때 JavaScript가 이를 추적하는 방법을 제공하지 않기 때문에 Svelte가 반응성을 유지하는 메커니즘이 없습니다.
간단한 말로 설명해준 Mat Simon에게 큰 감사를 드립니다. 제가 배운 내용은 다음과 같습니다.
문자열을 직접 사용할 수는 없지만 $state의 모든 객체(및 배열)는 Svelte 5에 의해 자동으로 프록시된 모든 값을 가져옵니다. 문자열 값을 객체로 래핑하면 다음과 같이 작동합니다.
// sharedState.svelte.js // ❌ export const searchState = $state(""); export const searchState = $state({ text : "" });
이것은 .text에 대한 getter 및 setter가 있는 Svelte 상태 개체로 바뀌었습니다. 원하는 속성 이름은 물론 여러 속성을 선택할 수 있습니다.
이 $state 객체를 가져온 다음 그런 다음 .text =를 작성하면 Svelte setter를 사용하여 상태를 업데이트하게 됩니다.
// App.svelte import { searchState } from './sharedState.svelte.js' function handleClick(){ // uses the automatically created setter searchState.text = "bicycles"; } <button onclick={handleClick}>Search for bicycles</button>
간단한 데모(REPL)): 구성 요소 간에 $state 공유(간단)
그리고 Svelte는 이러한 객체를 프록시하는 방법에 대해 정말 영리합니다. 이것이 바로 myList.push('foo')가 배열에서도 작동하는 이유입니다. Svelte가 푸시 메소드도 프록시했기 때문입니다.
// data.svelte.js export const myList = $state([]);
객체(배열 포함)를 사용할 때 객체 자체도 상태가 아닙니다! 이를 이해하는 것이 중요합니다.
이렇게 하면 반응성이 떨어집니다!
import { searchState } from './sharedState.svelte.js'; searchState = {text: "Hello world!"}; // don't do this!
Svelte가 이 문제를 처리할 방법이 없습니다. 항상 searchState.text = 'new value'를 통해 자동 Svelte getter/setter를 사용하세요.
좋아, 객체와 배열은 괜찮고 Svelte에서 자동으로 처리합니다. 우리는 그것을 얻었습니다.
그런데
표준 JavaScript의 날짜, URL 및 기타 내장 객체? JavaScript에 대한 경험이 더 많다면 몇 가지 고급 데이터 유형(표준 내장 개체)이 있다는 것을 알 수 있습니다.
Set 개체를 사용하면 기본 값이든 개체 참조이든 관계없이 모든 유형의 고유한 값을 저장할 수 있습니다.
Map 객체는 키-값 쌍을 보유하고 키의 원래 삽입 순서를 기억합니다.
이를 반응형 $state와 함께 사용하려면 svelte/reactivity에서 해당 Svelte 래퍼를 사용해야 합니다
// sharedState.svelte.js export const searchState = $state(""); // This won't work!
별도의 SvelteSet 및 SvelteMap 클래스가 있는 이유(객체 및 배열에서처럼 자동으로 다시 작성하는 대신)는 가능한 모든 객체를 프록시할 수 없기 때문에 어딘가에 선을 그리고 싶었기 때문입니다. 기술적인 세부 사항은 https://github.com/sveltejs/svelte/issues/10263을 참조하세요.
상태 객체를 정의하는 데는 여러 가지 옵션이 있으며, 사용자 정의 메서드용 클래스를 사용할 수도 있습니다: https://joyofcode.xyz/how-to-share-state-in-svelte-5#using-classes-for- 반응 상태
그래서 우리는 구성 요소 내부에서 상태를 가져오고 업데이트하는 방법을 알고 있으며 $state:
를 사용하여 즉시 객체와 배열을 사용할 수 있다는 것을 알고 있습니다.
<!-- App.svelte --> <script> import { searchState } from './sharedState.svelte.js' function handleClick(){ // This won't work! searchState = "bicycles"; } </script <button onclick={handleClick}>Search for bicycles</button>
$props를 사용하여 $state 객체를 속성의 참조로 전달할 수도 있습니다.
// sharedState.svelte.js // ❌ export const searchState = $state(""); export const searchState = $state({ text : "" });
// App.svelte import { searchState } from './sharedState.svelte.js' function handleClick(){ // uses the automatically created setter searchState.text = "bicycles"; } <button onclick={handleClick}>Search for bicycles</button>
하지만 구성 요소 내부에 있을 때 앱 어딘가에서 상태가 변경되었는지 어떻게 알 수 있나요? 이것이 바로 $derived 및 $derived.by의 용도입니다.
// data.svelte.js export const myList = $state([]);
간단한 데모(REPL)): 구성 요소 간에 $state 공유(간단)
이미 알고 계시겠지만, 텍스트 입력을 위한 핸들러 함수를 작성할 필요가 없습니다. 상태를 자동으로 업데이트하려면 바인딩:value={myStateObj}를 사용하면 됩니다.
import { searchState } from './sharedState.svelte.js'; searchState = {text: "Hello world!"}; // don't do this!
bind-group={stateObj}를 통해 Svelte에서도 여러 체크박스 입력을 처리할 수 있습니다. 하지만 $state에서 이를 올바르게 사용하는 방법에 대한 공개 토론이 여전히 진행 중입니다.
좋은 소식: 이를 수행하는 방법은 여러 가지가 있습니다. 아래를 참조하세요.
한 가지 방법은 onchange 이벤트 핸들러 함수 내에서 상태를 업데이트합니다.
간단한 데모(REPL): 체크박스 그룹 구성 요소와 v5 $state & $derived를 사용한 검색 및 필터링
전체 SvelteKit 예시(WIP): https://github.com/mandrasch/austrian-web-dev-companies
또한 더 많은 피드백을 얻기 위해 Reddit 토론을 시작했습니다.
Svelte v5($state)에서 검색 및 필터 확인란을 사용하는 가장 쉬운 방법은 무엇입니까?
여기에서 피드백을 받거나 여기에서 의견을 보내주시면 기쁩니다! ?
맷 사이먼에게 큰 감사를 드립니다!
위 내용은 구성 요소 간 Svelte 공유 상태(인형용)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!