Svelte:从子更新父状态
Svelte: update parent state from child
在反应中我可以做类似的事情:
App.jsx
const App = () => {
const [state, setState] = useState("old value")
return (
<>
<ChildComponent setState={setState} />
</>
)
}
ChildComponent.jsx
const ChildComponent = ({ setState }) => {
const changeState = () => setState("new value")
return (
<div>
<button onClick={changeState}>Click</button>
</div>
)
}
然后更新父状态。
我不知道如何在 Svelte 中做同样的事情...
我有这个:
index.svelte
<script>
import { ChildComponent } from "@components"
let state = "old value"
</script>
<main>
<ChildComponent {state} />
</main>
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>
并查看反映在父项中的新值。
我想在不使用商店的情况下做到这一点...我不知道这是否可能。
也许商店是继续进行的唯一途径。
我是耳朵
在 Svelte 中有两种方法可以做到这一点:
与two-way绑定
这将在父子之间创建一种连接,其中更新一个会自动更新另一个。
<!-- 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>
使用事件
就像道具向下一样,事件用于传递信息向上。如果您不希望两种状态之间存在严格的等价性并且更通用(但也更冗长),则可以使用此方法。
<!-- 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>
使用哪一个取决于您,可能取决于具体情况,但两者都有好处,因为它们不会主动依赖组件外部发生的事情。如果没有人使用 bind 组件不关心,它仍然有效。如果没有人在收听此事件,那么该组件也不会在意并继续工作。将此与未传递函数或函数签名错误的情况进行对比,您的组件突然依赖于它无法控制的东西,这不是一个好的模式。
在反应中我可以做类似的事情:
App.jsx
const App = () => {
const [state, setState] = useState("old value")
return (
<>
<ChildComponent setState={setState} />
</>
)
}
ChildComponent.jsx
const ChildComponent = ({ setState }) => {
const changeState = () => setState("new value")
return (
<div>
<button onClick={changeState}>Click</button>
</div>
)
}
然后更新父状态。
我不知道如何在 Svelte 中做同样的事情...
我有这个:
index.svelte
<script>
import { ChildComponent } from "@components"
let state = "old value"
</script>
<main>
<ChildComponent {state} />
</main>
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>
并查看反映在父项中的新值。
我想在不使用商店的情况下做到这一点...我不知道这是否可能。
也许商店是继续进行的唯一途径。
我是耳朵
在 Svelte 中有两种方法可以做到这一点:
与two-way绑定
这将在父子之间创建一种连接,其中更新一个会自动更新另一个。
<!-- 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>
使用事件
就像道具向下一样,事件用于传递信息向上。如果您不希望两种状态之间存在严格的等价性并且更通用(但也更冗长),则可以使用此方法。
<!-- 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>
使用哪一个取决于您,可能取决于具体情况,但两者都有好处,因为它们不会主动依赖组件外部发生的事情。如果没有人使用 bind 组件不关心,它仍然有效。如果没有人在收听此事件,那么该组件也不会在意并继续工作。将此与未传递函数或函数签名错误的情况进行对比,您的组件突然依赖于它无法控制的东西,这不是一个好的模式。