首页 > 解决方案 > 了解 Svelte tick() 生命周期

问题描述

我已经完成了 Svelte 文档的一半,我很难理解tick()生命周期。在 React 中有替代它的方法吗?

例如,它在本教程的这个示例中实际做了什么?

<script>
import { tick }  from 'svelte';
let text = `Select some text and hit the tab key to toggle uppercase`;

async function handleKeydown(event) {
    if (event.which !== 9) return;

    event.preventDefault();

    const { selectionStart, selectionEnd, value } = this;
    const selection = value.slice(selectionStart, selectionEnd);

    const replacement = /[a-z]/.test(selection)
        ? selection.toUpperCase()
        : selection.toLowerCase();

    text = (
        value.slice(0, selectionStart) +
        replacement +
        value.slice(selectionEnd)
    );

    await tick();
    this.selectionStart = selectionStart;
    this.selectionEnd = selectionEnd;
}
</script>

<style>
    textarea {
        width: 100%;
        height: 200px;
    }
</style>

<textarea value={text} on:keydown={handleKeydown}></textarea>

标签: javascriptsvelte

解决方案


当您更新变量时,它不会立即反映到 DOM 上,而是在下一个更新周期中与其他更改和更新一起批处理。

就像反应一样,如果你这样做

this.setState({ foo: 123 });

this.state.foo // you don't expect to read 123
// because this.setState is asynchronous!

让我们看一个例子,看看我们如何在 react vs svelte 中做到这一点

假设您有一个不断增长的文本输入,当您键入时,它的高度应该会增加,以容纳更多的文本。

这可能是你在 React 中的做法:

function GrowingTextInput() {
   const ref = useRef();
   const [value, setValue] = useState('');
   const updateText = (newValue) => {
     setValue(newValue);
     // NOTE: you can't measure the text input immediately
     // and adjust the height
     // you do it in useEffect
   }

   useEffect(() => {
     calculateAndAdjustHeight(ref.current, value);
   }, [value]);

   return <textarea value={value} ref={ref} />
}

在状态更新应用于 DOM 之后,您可以useEffect对 DOM 元素进行调整。

在 svelte 中,你会这样做:

<script>
  let ref;
  let value;
  const updateText = async (newValue) => {
     value = newValue;
     // NOTE: you can't measure the text input immediately
     // and adjust the height, you wait for the changes to be applied to the DOM
     await tick();
     calculateAndAdjustHeight(ref, value);
   }
</script>

<textarea bind:this={ref} {value} />

在 svelte 中,要等待应用的状态更改,您需要等待返回的承诺tick()被解决。


如果您更喜欢视觉效果,我已尝试在 youtube 视频中对其进行解释:

https://youtu.be/JjONMdhaCDs

此外,这是我对您可能使用的其他用例的看法tick()

https://dev.to/tanhauhau/2-amazing-use-case-of-tick-in-svelte-that-you-must-know-8pa


推荐阅读