서동휘
서동휘
SSolidJS
Created by 서동휘 on 2/6/2024 in #support
How do I use Solid.js with clear data model <-> UI primitive distinction?
Suppose I have a ES6 Map object like following:
const initialFiles = new Map([
["a.txt", "foo"],
["b.txt", "bar"],
["c.txt", "baz"],
])
const initialFiles = new Map([
["a.txt", "foo"],
["b.txt", "bar"],
["c.txt", "baz"],
])
Then using Solid.JS, I want to create an user interface to modify this object.
function App() {
  const [files, setFiles] = createSignal(initialFiles);

  const handleFileChange = (fileName: string, value: string) => {
    const newFiles = new Map(files());
    newFiles.set(fileName, value);
    setFiles(newFiles);
  };

  return (
    <div>
      <FileEditor
        value={files().get("a.txt") ?? ""}
        onChange={(value) => handleFileChange("a.txt", value)}
      />

      <FileEditor
        value={files().get("b.txt") ?? ""}
        onChange={(value) => handleFileChange("b.txt", value)}
      />

      <FileEditor
        value={files().get("b.txt") ?? ""}
        onChange={(value) => handleFileChange("a.txt", value)}
      />
    </div>
  );
}
function App() {
  const [files, setFiles] = createSignal(initialFiles);

  const handleFileChange = (fileName: string, value: string) => {
    const newFiles = new Map(files());
    newFiles.set(fileName, value);
    setFiles(newFiles);
  };

  return (
    <div>
      <FileEditor
        value={files().get("a.txt") ?? ""}
        onChange={(value) => handleFileChange("a.txt", value)}
      />

      <FileEditor
        value={files().get("b.txt") ?? ""}
        onChange={(value) => handleFileChange("b.txt", value)}
      />

      <FileEditor
        value={files().get("b.txt") ?? ""}
        onChange={(value) => handleFileChange("a.txt", value)}
      />
    </div>
  );
}
But the problem with this is that editing a single file causes the re-render of the entire App. The solution I have found is using ReactiveMap (https://www.npmjs.com/package/@solid-primitives/map), which is a reactive variant of ES6 Map. It works fine. However I feel like I am altering the data model only because of the choice of UI library. I will be passing files object to other functions which are irrelevant to Solid.JS, and they have to know what ReactiveMap is. Seems like a sign of bad abstraction. What would be a nicer way to handle this without losing fine-grained reactivity? Thank you 🙂
5 replies