Svelte:从子级更新父级状态

Die*_*loa 12 javascript svelte

在反应中我可以做类似的事情:

App.jsx

const App = () => {
  const [state, setState] = useState("old value")

  return (
    <>
      <ChildComponent setState={setState} />
    </>
  )
}
Run Code Online (Sandbox Code Playgroud)

ChildComponent.jsx

const ChildComponent = ({ setState }) => {
  const changeState = () => setState("new value")

  return (
    <div>
      <button onClick={changeState}>Click</button>
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

然后父状态将被更新。

我不知道如何在 Svelte 中做同样的事情......

我有这个:

index.svelte

<script>
  import { ChildComponent } from "@components"

  let state = "old value"
</script>

<main>
  <ChildComponent {state} />
</main>
Run Code Online (Sandbox Code Playgroud)

ChildComponent.svelte

<script>
  export let state

  const changeState = () => {
    // I need to do something like:
    state = "new value"
  }
 </script>

<div>
  <button on:click={changeState}>Click</button>
</div>
Run Code Online (Sandbox Code Playgroud)

并查看父级中反映的新值。

我想在不使用商店的情况下做到这一点...我不知道这是否可能。

也许商店是唯一的出路。

我是耳朵

Ste*_*aes 27

在 Svelte 中有两种方法可以做到这一点:

具有双向绑定功能

这将在父级和子级之间创建一种连接,其中更新一个将自动更新另一个。

<!-- Parent.svelte -->
<script>
 import Child from './Child.svelte';
 let state = "initial";
</script>

<Child bind:state />

<!-- Child.svelte -->
<script>
  export let state;
 function changeState() {
   state = "new value";
</script>

<button on:click={changeState}>Click</button>
Run Code Online (Sandbox Code Playgroud)

使用事件

就像 props 向下传递一样事件也用于向上传递信息。如果您不想在两种状态之间严格等效并且更通用(但也更冗长),则可以使用此方法。

<!-- Parent.svelte -->
<script>
  import Child from './Child.svelte';
  let state = "initial"
 
  function handleChange(ev) {
    state = ev.detail.state
  }
</script>

<Child {state} on:change={handleChange} />


<!-- Child.svelte -->
<script>
  import { createEventDispatcher } from 'svelte';
  export let state

  const dispatch = createEventDispatcher()

  function changeState() {
    // first argument is the event name
    // second is an object placed in ev.detail
    dispatch('change', { state: "new value" });
  }
</script>

<button on:click={changeState}>Click</button>
Run Code Online (Sandbox Code Playgroud)

使用哪一个取决于您,并且可能取决于具体情况,但两者都有好处,因为它们不主动依赖于组件外部发生的事情。如果没有人使用绑定组件并不关心,它仍然可以工作。如果没有人监听此事件,该组件将不再关心并继续工作。将此与没有传递函数或函数具有错误签名的情况进行对比,突然您的组件依赖于它无法控制的东西,这不是一个好的模式。