SOLIDJS:for和索引之间的差异
#javascript #网络开发人员 #solidjs

SolidJS中有ForIndex组件有效地渲染数组元素。 array.map效率低下,因为它总是映射整个数组。


为了

For组件是循环在一系列对象上的最佳方法。随着数组的变化,更新或移动DOM中的项目而不是重新创建它们。

指数

实心还提供了Index组件,在某些情况下会导致较少的重读者。


例如

import { For, createSignal } from "solid-js";

const initialPeople = [
  {
    name: "Amy",
    age: 15,
  },
  {
    name: "Bob",
    age: 25,
  },
  {
    name: "Charlee",
    age: 20,
  },
];

function ForComp() {
  const [people, setPeople] = createSignal(initialPeople);

  const changeAge = (personIdx) => () => {
    const newPeople = [...people()];
    newPeople[personIdx] = {
      ...newPeople[personIdx],
      age: Math.floor(Math.random() * 30),
    };
    setPeople(newPeople);
  };

  return (
    <>
      <For each={people()}>
        {(person, personIdx) => {
          console.log(`person(${personIdx()}) has rendered.`);

          return (
            <div style={{ cursor: "pointer" }} onClick={changeAge(personIdx())}>
              <h6>
                Name: {person.name} Age: {person.age}
              </h6>
            </div>
          );
        }}
      </For>
    </>
  );
}

function App() {
  return <ForComp />;

example site

如果单击第二项,则将像以下图像一样更改第二项的年龄。

the age of the second item has changed

如果您更改对象的一部分,则不会显示任何更改。

 const changeAge = (personIdx) => () => {
    const newPeople = [...people()];
    newPeople[personIdx].age = Math.floor(Math.random() * 30);
    setPeople(newPeople);
  };

这是不起作用的,因为即使对象的字段已更改,对象也保持不变。


索引示例

function IndexComp() {
  const [people, setPeople] = createSignal(initialPeople);

  const changeAge = (personIdx) => () => {
    const newPeople = [...people()];
    newPeople[personIdx] = {
      ...newPeople[personIdx],
      age: Math.floor(Math.random() * 30),
    };
    setPeople(newPeople);
  };

  return (
    <>
      <Index each={people()}>
        {(person, personIdx) => {
          console.log(`INDEX: person(${personIdx}) has rendered.`);

          return (
            <div style={{ cursor: "pointer" }} onClick={changeAge(personIdx)}>
              <h6>
                Name: {person().name} Age: {person().age}
              </h6>
            </div>
          );
        }}
      </Index>
    </>
  );
}

function App() {
  return (
    <>
      <h1>For</h1>
      <ForComp />
      <hr />
      <h1>Index</h1>
      <IndexComp />
    </>
  );
}

index component example

no re-render even when the field of an object is changed

Index组件重新呈现当索引更改时,当For component更改其值时。

但是您仍然可以看到数据已更改,因为person()return中使用。

return (
    <>
      <Index each={people()}>
        {(person, personIdx) => {
          console.log(`INDEX: person(${personIdx}) has rendered.`);
          const p = person();

          return (
            <div style={{ cursor: "pointer" }} onClick={changeAge(personIdx)}>
              <h6>
                Name: {p.name} Age: {p.age}
              </h6>
            </div>
          );
        }}
      </Index>
    </>
  );

如果您的人()在渲染函数中使用,则数据将不会更改。这就是SolidJS的工作方式。

no changes even when an item is clicked


添加新项目

import { For, createSignal } from "solid-js";

const initialPeople = [
  {
    name: "Amy",
    age: 15,
  },
  {
    name: "Bob",
    age: 25,
  },
  {
    name: "Charlee",
    age: 20,
  },
];

function ForComp() {
  const [people, setPeople] = createSignal(initialPeople);

  const changeAge = (personIdx) => () => {
    const newPeople = [...people()];
    newPeople[personIdx] = {
      ...newPeople[personIdx],
      age: Math.floor(Math.random() * 30),
    };
    setPeople(newPeople);
  };

  const addNewPerson = () => {
    setPeople(
      people().concat({
        people: "Delta",
        age: 50,
      })
    );
  };

  return (
    <>
      <button onClick={addNewPerson}>Add New Person</button>
      <For each={people()}>
        {(person, personIdx) => {
          console.log(`FOR: person(${personIdx()}) has rendered.`);

          return (
            <div style={{ cursor: "pointer" }} onClick={changeAge(personIdx())}>
              <h6>
                Name: {person.name} Age: {person.age}
              </h6>
            </div>
          );
        }}
      </For>
    </>
  );
}

function IndexComp() {
  const [people, setPeople] = createSignal(initialPeople);

  const changeAge = (personIdx) => () => {
    const newPeople = [...people()];
    newPeople[personIdx] = {
      ...newPeople[personIdx],
      age: Math.floor(Math.random() * 30),
    };
    setPeople(newPeople);
  };

  const addNewPerson = () => {
    setPeople(
      people().concat({
        people: "Delta",
        age: 50,
      })
    );
  };

  return (
    <>
      <button onClick={addNewPerson}>Add New Person</button>
      <Index each={people()}>
        {(person, personIdx) => {
          console.log(`INDEX: person(${personIdx}) has rendered.`);
          const p = person();

          return (
            <div style={{ cursor: "pointer" }} onClick={changeAge(personIdx)}>
              <h6>
                Name: {p.name} Age: {p.age}
              </h6>
            </div>
          );
        }}
      </Index>
    </>
  );
}

function App() {
  return (
    <>
      <h1>For</h1>
      <ForComp />
      <hr />
      <h1>Index</h1>
      <IndexComp />
    </>
  );
}

add new item

对于新项目,

都呈现新项目。

结论

如果您希望数据更改不需要影响渲染,而index仅重要,那么Index将是一个不错的选择,然后For以获得更好的性能。

我希望您在本文中发现它很有用。

快乐编码!