每个 Solidjs 中的列表项在每次更改时都会挂载,这正常吗?

huangapple go评论49阅读模式
英文:

Is this normal that each list item in Solidjs is mounting on every change?

问题

在 Solidjs 中,每次更改时每个列表项都会挂载,这是正常的吗?

import { Component, createSignal, For } from 'solid-js';

const data = [
  {name: 'Helen'},
  {name: 'Peter'},
  {name: 'Maksim'},
]

const Card: Component = (props: {name: string}) => {
  console.log('card'); // 它在每次点击时运行,这不是我预期的

  return <div>
   <span>姓名</span>
   <span>{props.name}</span>
 </div>
}

export const App: Component = () => {
  const [users, setUsers] = createSignal(data)

  return (
    <>
      <button onClick={() => setUsers(users => users.map(user => ({...user, name: 'Suzy'})))}>点击</button>
      <For  each={users()}>{user => <Card {...user} />}</For>
    </>
  );
};

对于 createStore 也是一样的情况。

英文:

Is this normal that each list item in Solidjs is mounting on every change?

import { Component, createSignal, For } from &#39;solid-js&#39;;

const data = [
  {name: &#39;Helen&#39;},
  {name: &#39;Peter&#39;},
  {name: &#39;Maksim&#39;},
]

const Card: Component = (props: {name: string}) =&gt; {
  console.log(&#39;card&#39;); // It runs on every click which I&#39;m not expecting 

  return &lt;div&gt;
   &lt;span&gt;Name: &lt;/span&gt;
   &lt;span&gt;{props.name}&lt;/span&gt;
 &lt;/div&gt;
}

export const App: Component = () =&gt; {
  const [users, setUsers] = createSignal(data)

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; setUsers(users =&gt; users.map(user =&gt; ({...user, name: &#39;Suzy&#39;})))}&gt;Click&lt;/button&gt;
      &lt;For  each={users()}&gt;{user =&gt; &lt;Card {...user} /&gt;}&lt;/For&gt;
    &lt;/&gt;
  );
};

The same happens with createStore.

答案1

得分: 1

这是正常的,因为您正在通过在setUsers上映射项目并创建具有相同值的新对象来更新setUsers中的每个列表项。尽管您使用先前的值,但您正在创建新对象。

For保留项目的引用,如果数组项不更改。它的内部逻辑类似于这样:

const cache = {};
cache[user] = <Card />

由于您正在更改每个数组项,通过丢弃旧键来使缓存无效,因此将呈现新项目。当呈现此新项目时,Card被挂载。

尝试这段代码,在这个代码中,我们只更新了第一个项目:

import { Component, createSignal, For } from 'solid-js';
import { render } from 'solid-js/web';

const data = [{ name: 'Helen' }, { name: 'Peter' }, { name: 'Maksim' }];

const Card: Component<{ name: string }> = (props) => {
  console.log(props.name);
  return (
    <div>
      <span>Name: </span>
      <span>{props.name}</span>
    </div>
  );
};

export const App = () => {
  const [users, setUsers] = createSignal(data);

  const handleClick = () =>
    setUsers((users) => [
      ...users.map((val, i) => (i === 0 ? { ...val } : val)),
    ]);

  return (
    <>
      <button onClick={handleClick}>Click</button>
      <For each={users()}>{(user) => <Card {...user} />}</For>
    </>
  );
};

render(App, document.body);
英文:

That is normal because you are updating every list item inside setUsers by mapping over items and creating a new object that has the same values. Although you use previous values, you are creating new object.

For keeps the reference of an item if the array item does not change. Its internal logic is something like this:

const cache = {};
cache[user] = &lt;Card /&gt;

Since you are changing every array items, invalidating the cache by throwing away the old key, hence a new item is rendered. When this new item is rendered, Card is mounted.

Try this code, in this one we are updating only the first item:

import { Component, createSignal, For } from &#39;solid-js&#39;;
import { render } from &#39;solid-js/web&#39;;

const data = [{ name: &#39;Helen&#39; }, { name: &#39;Peter&#39; }, { name: &#39;Maksim&#39; }];

const Card: Component&lt;{ name: string }&gt; = (props) =&gt; {
  console.log(props.name);
  return (
    &lt;div&gt;
      &lt;span&gt;Name: &lt;/span&gt;
      &lt;span&gt;{props.name}&lt;/span&gt;
    &lt;/div&gt;
  );
};

export const App = () =&gt; {
  const [users, setUsers] = createSignal(data);

  const handleClick = () =&gt;
    setUsers((users) =&gt; [
      ...users.map((val, i) =&gt; (i === 0 ? { ...val } : val)),
    ]);

  return (
    &lt;&gt;
      &lt;button onClick={handleClick}&gt;Click&lt;/button&gt;
      &lt;For each={users()}&gt;{(user) =&gt; &lt;Card {...user} /&gt;}&lt;/For&gt;
    &lt;/&gt;
  );
};

render(App, document.body);

huangapple
  • 本文由 发表于 2023年5月29日 14:28:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76355105.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定