svelte - svelte 中的 react 减速未按预期工作

标签 svelte

我正在尝试创建一个 TextAreaAutosize 组件,它返回一个文本区域,在需要时自动调整其高度。

我想在高度变化时运行 onHeightChange 函数,因此我使用了 svelte react 语句($:),以便每当高度变化时,该代码段都会运行。

App.svelte

<script>
  import TextArea from "./TextAreaAutosize.svelte";
  let val, ref;
</script>

<TextArea 
  bind:value={val}  
  bind:ref={ref} 
  style={"height: 90px; maxHeight=40"} 
  minRows={4}
 />

TextAreaAutosize.svelte

<script context="module">
  import calculateNodeHeight from './calculateNodeHeight.js'
  let uid = 0;
  const noop = () => {};
</script>

<script>
  export let value = '';
  export let style;
  export let useCacheForDOMMeasurements = false;
  export let minRows = -Infinity;
  export let maxRows = +Infinity;
  export let onHeightChange = noop;
  export let ref = null;

  let refConfig = {
    _uid: uid++
  }

  let state = {
    height: 0,
    minHeight: -Infinity,
    maxHeight: +Infinity
  }

  // runs when change in height
  $: if(state.height){

    //block 1

    console.log('height changed')
    onHeightChange(refConfig)

  }

  // resizes element on initial mount or whenever change in value
  $:if(ref || value){

     //block 2

    _resizeComponent()

  }

  // function for resizing textarea when required
  function _resizeComponent(){
    if(!ref){
      return;
    }

    const refHeight = calculateNodeHeight(
      ref,
      refConfig._uid,
      useCacheForDOMMeasurements,
      minRows,
      maxRows
    );

    const {
      height,
      minHeight,
      maxHeight,
      rowCount,
      valueRowCount
    } = refHeight;

    refConfig.rowCount = rowCount;
    refConfig.valueRowCount = rowCount;

    if(
      state.height !== height ||
      state.maxHeight !== maxHeight ||
      state.minHeight !== minHeight
    ){
      state = {height, minHeight, maxHeight}
    }
  }

</script>

<textarea 
  bind:value={value} 
  bind:this={ref} 
  style={`${style};height: ${state.height}px;`}
  on:click
  on:change  
  class={$$props.class}
/>

在此组件中,只要 state.height 发生变化, block 1 就应该运行。但它根本不运行。但是当我将它放在 block2 之后时,只要 state.height 发生变化,它就会运行

当文本区域的值发生变化时,block2 运行并调用 _resizeComponent,然后根据需要用新的高度更新状态。如果高度变化,应该触发 block1。但只有当我将其放在 block2 之后时才会触发该 block

我无法理解为什么我的代码中会出现这种行为。无论 react 语句的顺序如何,只要 state.height 发生变化,block1 中的语句都应该运行

最佳答案

Svelte 通过分析该代码无法确定第二个 block 可能会影响 state 的值。因此它不会对 block 重新排序以先运行第二个 block 。 (如果最后出现意外的变化,它不能只是继续重新运行 react block ;这样就会形成无限循环。)

如果不仅仅是 _resizeComponent() 而是 state = _resizeComponent(),并且函数也相应地更改,那么情况就会改变。或者,只需手动重新排序 block 。

顺便说一句,有一个更简单的方法来获得自动调整大小的文本区域:https://svelte.dev/repl/40f4c7846e6f4052927ff5f9c5271b66?version=3.6.8

关于svelte - svelte 中的 react 减速未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57062407/

相关文章:

javascript - 自定义 Svelte Material UI slider 标签

bootstrap-4 - 如何在 svelte 中导入 bootstrap 主题?

javascript - 将变量传递给自定义 Svelte Web 组件

typescript - 作为对象属性的 Svelte 组件

Svelte/Sapper 如何在不提供绝对 URL 的情况下从内部 api 获取数据

javascript - 如何专注于 Svelte 中新增的输入?

javascript - 如何在 Vercel 上的 SvelteKit 应用程序中创建 Web Worker?

navigation - Sveltekit 根路由不会导致页面加载

svelte - 如何在 svelte 3 中强制渲染?

javascript - Svelte/Sapper - 无法保存不同路线上 api 响应的数据