บล็อกนี้เราจะมาทำความรู้จักไลบรารี่ใหม่ที่คล้ายๆ กับ React ที่ใช้ในการพัฒนาเว็บแอปพลิเคชัน ชื่อของไลบรารี่นี้ก็คือ SolidJS
SolidJS ไลบรารี่นี้เอาไว้ใช้สร้างเว็บแอปพลิเคชันแบบ Reactive มีการสร้าง Component ที่สามารถนำกลับมาใช้งานใหม่ได้ และรองรับการสร้าง Component ด้วย JSX เหมือนกับ React เลย (ถ้าเรามีพื้นฐาน React ที่ดีแล้ว ปรับจูนเรื่องโครงสร้างภาษาอีกนิดหน่อยก็สามารถใช้งาน SolidJS ได้อย่างง่ายดายแล้ว)
โค้ดของ React และ SolidJS ทั้งสองไลบรารี่ รองรับการแสดงผล Component ด้วย JSX เหมือนกัน จะสังเกตุว่า JSX จะแตกต่างจาก HTML ทั่วไปคือ ทุก tag จะต้องมี tag เปิด และ ปิด เสมอ เช่น
<div>Hello World!</div>
ส่วน HTML บางตัว ไม่จำเป็นต้องมี tag ปิดก็ได้ เช่น <input type=”text” name=”label”> tag แบบนี้จะใช้ไม่ได้ใน JSX
เรามาดูตัวอย่างโค้ดของ React และ SolidJS ในการสร้าง Component ง่ายๆ กัน
import ReactDOM from "react-dom";
export default function App() {
return <div>Hello World!</div>;
}
ReactDOM.render(<App />,document.getElementById("root"));
import { render } from 'solid-js/web';
function HelloWorld() {
return <div>Hello World!</div>;
}
render(() => <HelloWorld />, document.getElementById('app'))
ตัวอย่างที่ 2 ทดสอบการรองรับการแสดงผล Component ที่ซ้อนกัน โดย ทั้ง React และ SolidJS นั้นสามารถแสดงผล Component ที่ซ้อนกันได้ และการแสดงผล Component ในแต่ละตัวนั้นจะต้องอยู่บน Root Fragment เท่านั้น (จะมี Root Component เพียง 1 อันเท่านั้น อย่างเช่นในตัวอย่างจะใช้ <> … </>)
import ReactDOM from "react-dom";
const NestedComp = () => <p>This is a Paragraph</p>;
export default function App() {
return (
<>
<div>Hello World!</div>
<NestedComp />
</>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
import { render } from "solid-js/web";
const NestedComp = ()=> <p>This is a Paragraph</p>
function App() {
return (
<>
<h1>This is a Header</h1>
<NestedComp />
</>
);
}
render(() => <App />, document.getElementById("app"));
จากตัวอย่างในข้อ 1 และ 2 จะเห็นว่าทั้ง React และ SolidJS นั้นรองรับการเขียนโปรแกรมแบบ function และ สามารถสร้าง Component ที่เป็นแบบ Function Component ได้ด้วย
ส่วนการรองรับ hook function ทั้ง React และ SolidJS ก็รองรับเช่นกัน ตัวอย่างจะแสดงในข้อถัดไป เช่นการใช้ useState, createSignal, useEffect, createEffect เป็นต้น
import ReactDOM from "react-dom";
import { useEffect, useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
setInterval(() => setCount((c) => c + 1), 1000);
}, []);
return <div>Count: {count}</div>;
}
ReactDOM.render(<Counter />, document.getElementById("root"));
import { render } from "solid-js/web";
import { createSignal } from "solid-js";
function Counter() {
const [count, setCount] = createSignal(0);
setInterval(() => setCount(count() + 1), 1000);
return <div>Count: {count()}</div>;
}
render(() => <Counter />, document.getElementById('app'));
// ประกาศตัวแปร Signal ชื่อว่า count เป็นฟังก์ชันที่เรียกใช้เพื่อดูค่าข้อมูล และ setCount เป็นฟังก์ชันที่เรียกใช้เพื่อแก้ไขข้อมูล
const [count, setCount] = createSignal(0);
// ตัวอย่างการเรียกใช้ count จะต้องเรียกแบบฟังก์ชัน คือ count()
return <div>Count: {count()}</div>;
// ตัวอย่างการเรียกใช้ setCount จะต้องเรียกแบบฟังก์ชัน คือ setCount(param)
setCount(count() + 1)
import { render } from 'solid-js/web';
import { createSignal, createEffect } from 'solid-js';
function Counter() {
const [count, setCount] = createSignal(0);
createEffect(() => {
console.log("The count is now", count());
});
return <button onClick={() => setCount(count() + 1)}>Click Me</button>;
}
render(() => <Counter />, document.getElementById('app'));
import { render } from 'solid-js/web';
import { createSignal, createMemo } from 'solid-js';
function fibonacci(num) {
if (num <= 1) return 1;
return fibonacci(num - 1) + fibonacci(num - 2);
}
function Counter() {
const [count, setCount] = createSignal(10);
const fib = createMemo(() => fibonacci(count()));
return (
<>
<button onClick={() => setCount(count() + 1)}>Count: {count()}</button>
<div>1. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>2. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>3. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>4. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>5. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>6. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>7. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>8. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>9. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
<div>10. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
</>
);
}
render(() => <Counter />, document.getElementById('app'))
import { render } from 'solid-js/web';
import { createSignal, Show } from 'solid-js';
function App() {
const [loggedIn, setLoggedIn] = createSignal(false);
const toggle = () => setLoggedIn(!loggedIn())
return (
<Show
when={loggedIn()}
fallback={() => <button onClick={toggle}>Log in</button>}
>
<button onClick={toggle}>Log out</button>
</Show>
);
}
render(() => <App />, document.getElementById('app'))
import { render } from 'solid-js/web';
import { createSignal, For } from 'solid-js';
function App() {
const [cats, setCats] = createSignal([
{ id: 'J---aiyznGQ', name: 'Keyboard Cat' },
{ id: 'z_AbfPXTKms', name: 'Maru' },
{ id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
]);
return (
<ul>
<For each={cats()}>{(cat, i) =>
<li>
<a target="_blank" href={`https://www.youtube.com/watch?v=${cat.id}`}>
{i() + 1}: {cat.name}
</a>
</li>
}</For>
</ul>
);
}
render(() => <App />, document.getElementById('app'))
import { render } from 'solid-js/web';
import { createSignal, Index } from 'solid-js';
function App() {
const [cats, setCats] = createSignal([
{ id: 'J---aiyznGQ', name: 'Keyboard Cat' },
{ id: 'z_AbfPXTKms', name: 'Maru' },
{ id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
]);
return (
<ul>
<Index each={cats()}>{(cat, i) =>
<li>
<a target="_blank" href={`https://www.youtube.com/watch?v=${cat().id}`}>
{i + 1}: {cat().name}
</a>
</li>
}</Index>
</ul>
);
}
render(() => <App />, document.getElementById('app'))
การใช้งาน For และ Index ที่เป็น component ในไลบรารี่ของ Solid นั้น จะมีข้อแตกต่างในการใช้งาน ดังนี้
import { render } from "solid-js/web";
import { createSignal, Switch, Match } from "solid-js";
function App() {
const [x] = createSignal(7);
return (
<Switch fallback={<p>{x()} is between 5 and 10</p>}>
<Match when={x() > 10} >
<p>{x()} is greater than 10</p>
</Match>
<Match when={5 > x()}>
<p>{x()} is less than 5</p>
</Match>
</Switch>
);
}
render(() => <App />, document.getElementById("app"));
import { createSignal, createContext, useContext } from "solid-js";
const CounterContext = createContext();
export function CounterProvider(props) {
const [count, setCount] = createSignal(props.count || 0),
store = [
count,
{
increment() {
setCount(c => c + 1);
},
decrement() {
setCount(c => c - 1);
}
}
];
return (
<CounterContext.Provider value={store}>
{props.children}
</CounterContext.Provider>
);
}
export function useCounter() { return useContext(CounterContext); }
การนำ CounterProvider ไปใช้งานที่ component ที่ต้องการส่งผ่านค่า count และ ใช้งานฟังก์ชัน setCount
import { render } from "solid-js/web";
import Nested from "./nested";
import { CounterProvider } from "./counter";
function App() {
return <>
<h1>Welcome to Counter App</h1>
<Nested />
</>
};
render(() => (
<CounterProvider count={1}>
<App />
</CounterProvider>
), document.getElementById("app"));
import { useCounter } from "./counter";
export default function Nested() {
const [count, { increment, decrement }] = useCounter();
return (
<>
<div>{count()}</div>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</>
);
};
SolidJS เป็นไลบรารี่ที่ช่วยอำนวยความสะดวกในการสร้างเว็บแอปพลิเคชัน แบบ Reactive ได้ โดยจะมีโครงการการเขียนโปรแกรมคล้ายกับ ReactJS หากเรามีพื้นฐานการเขียน React อยู่แล้วก็จะสามารถเรียนรู้ SolidJS ได้เร็วยิ่งขึ้น
ข้อดีของ SolidJS คือเรื่องของประสิทธิภาพการทำงาน สามารถรันผลลัพธ์ได้เร็วเทียบเท่ากับการรันของ JavaScript ปกติ (ช้ากว่า JavaScript ปกติเพียง 1.05 เท่า) และ รองรับภาษา TypeScript
ตัวอย่างไลบรารี่ที่น่าสนใจของ SolidJS ดังนี้
SolidJS ก็เป็นอีกหนึ่งไลบรารี่ที่น่าสนใจ และในไลบรารี่ที่ SolidJS เตรียมไว้ให้นั้นยังมีเรื่องที่น่าสนใจอยู่อีกมากมาย สามารถศึกษาต่อได้ตามลิ้งอ้างอิงได้เลยครับ
Git is a versio…
React Hooks are…
https://www.tik…
https://www.tik…
This website uses cookies.