![](/style/images/good.png)
3
![](/style/images/bad.png)
Component Party
source link: https://component-party.dev/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Reactivity#
Declare state#
<script>
let name = 'John';
</script>
<h1>Hello {name}</h1>
import { useState } from 'react';
export default function Name() {
const [name] = useState('John');
return <h1>Hello {name}</h1>;
}
Update state#
<script>
let name = 'John';
name = 'Jane';
</script>
<h1>Hello {name}</h1>
import { useState } from 'react';
export default function Name() {
const [name, setName] = useState('John');
setName('Jane');
return <h1>Hello {name}</h1>;
}
Computed state#
<script>
let count = 10;
$: doubleCount = count * 2;
</script>
<div>{doubleCount}</div>
import { useState, useMemo } from 'react';
export default function DoubleCount() {
const [count] = useState(10);
const doubleCount = useMemo(() => count * 2, [count]);
return <div>{doubleCount}</div>;
}
Templating#
Minimal template#
<h1>Hello world</h1>
export default function HelloWorld() {
return <h1>Hello world</h1>;
}
Styling#
<h1 class="title">I am red</h1>
<button style="font-size: 10rem;">I am a button</button>
<style>
.title {
color: red;
}
</style>
import './style.css';
export default function CssStyle() {
return (
<>
<h1 className="title">I am red</h1>
<button style={{ 'font-size': '10rem' }}>I am a button</button>
</>
);
}
Loop#
<script>
const colors = ['red', 'green', 'blue'];
</script>
<ul>
{#each colors as color}
<li>{color}</li>
{/each}
</ul>
export default function Colors() {
const colors = ['red', 'green', 'blue'];
return (
<ul>
{colors.map((color) => (
<li key={color}>{color}</li>
))}
</ul>
);
}
Event click#
<script>
let count = 0;
function incrementCount() {
count++;
}
</script>
<p>Counter: {count}</p>
<button on:click={incrementCount}>+1</button>
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
function incrementCount() {
setCount((count) => count + 1);
}
return (
<>
<p>Counter: {count}</p>
<button onClick={incrementCount}>+1</button>
</>
);
}
Dom ref#
<script>
import { onMount } from 'svelte';
let inputElement;
onMount(() => {
inputElement.focus();
});
</script>
<input bind:this={inputElement} />
import { useEffect, useRef } from 'react';
export default function InputFocused() {
const inputElement = useRef(null);
useEffect(() => inputElement.current.focus(), []);
return <input type="text" ref={inputElement} />;
}
Conditional#
<script>
const TRAFFIC_LIGHTS = ['red', 'orange', 'green'];
let lightIndex = 0;
$: light = TRAFFIC_LIGHTS[lightIndex];
function nextLight() {
if (lightIndex + 1 > TRAFFIC_LIGHTS.length - 1) {
lightIndex = 0;
} else {
lightIndex++;
}
}
</script>
<button on:click={nextLight}>Next light</button>
<p>Light is: {light}</p>
<p>
You must
{#if light === 'red'}
<span>STOP</span>
{:else if light === 'orange'}
<span>SLOW DOWN</span>
{:else if light === 'green'}
<span>GO</span>
{/if}
</p>
import { useState } from 'react';
const TRAFFIC_LIGHTS = ['red', 'orange', 'green'];
export default function TrafficLight() {
const [lightIndex, setLightIndex] = useState(0);
const light = TRAFFIC_LIGHTS[lightIndex];
function nextLight() {
if (lightIndex + 1 > TRAFFIC_LIGHTS.length - 1) {
setLightIndex(0);
} else {
setLightIndex(lightIndex + 1);
}
}
return (
<>
<button onClick={nextLight}>Next light</button>
<p>Light is: {light}</p>
<p>
You must
{light === 'red' && <span>STOP</span>}
{light === 'orange' && <span>SLOW DOWN</span>}
{light === 'green' && <span>GO</span>}
</p>
</>
);
}
Lifecycle#
On mount#
<script>
import { onMount } from 'svelte';
let pageTitle = '';
onMount(() => {
pageTitle = document.title;
});
</script>
<p>Page title is: {pageTitle}</p>
import { useState, useEffect } from 'react';
export default function PageTitle() {
const [pageTitle, setPageTitle] = useState('');
useEffect(() => {
setPageTitle(document.title);
}, []);
return <p>Page title: {pageTitle}</p>;
}
On unmount#
<script>
import { onDestroy } from 'svelte';
let time = new Date().toLocaleTimeString();
const timer = setInterval(() => {
time = new Date().toLocaleTimeString();
}, 1000);
onDestroy(() => clearInterval(timer) );
</script>
<p>Current time: {time}</p>
import { useState, useEffect } from 'react';
export default function Time() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const timer = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
return <p>Current time: {time}</p>;
}
Component composition#
Props#
<script>
import UserProfile from './UserProfile.svelte';
</script>
<UserProfile name="John" age={20} favouriteColors={['green', 'blue', 'red']} isAvailable />
import UserProfile from './UserProfile.jsx';
export default function App() {
return <UserProfile name="John" age={20} favouriteColors={['green', 'blue', 'red']} isAvailable />;
}
Emit to parent#
<script>
import AnswerButton from './AnswerButton.svelte';
let canCome = true;
function onAnswerNo() {
canCome = false;
}
function onAnswerYes() {
canCome = true;
}
</script>
<p>Can I come ?</p>
<AnswerButton on:yes={onAnswerYes} on:no={onAnswerNo} />
<p style="font-size: 50px;">{canCome ? '😀' : '😥'}</p>
import { useState } from 'react';
import AnswerButton from './AnswerButton.jsx';
export default function App() {
const [canCome, setCanCome] = useState(true);
function onAnswerNo() {
setCanCome(false);
}
function onAnswerYes() {
setCanCome(true);
}
return (
<>
<p>Can I come ?</p>
<AnswerButton onYes={onAnswerYes} onNo={onAnswerNo} />
<p style={{ fontSize: 50 }}>{canCome ? '😀' : '😥'}</p>
</>
);
}
Slot#
<script>
import FunnyButton from './FunnyButton.svelte';
</script>
<FunnyButton>Click me !</FunnyButton>
import FunnyButton from './FunnyButton.jsx';
export default function App() {
return <FunnyButton>Click me !</FunnyButton>;
}
Slot fallback#
<script>
import FunnyButton from './FunnyButton.svelte';
</script>
<FunnyButton />
<FunnyButton>I got content !</FunnyButton>
import FunnyButton from './FunnyButton.jsx';
export default function App() {
return (
<>
<FunnyButton />
<FunnyButton>I got content !</FunnyButton>
</>
);
}
Form input#
Input text#
<script>
let text = 'Hello World';
</script>
<p>{text}</p>
<input bind:value={text} />
import { useState } from 'react';
export default function InputHello() {
const [text, setText] = useState('Hello world');
function handleChange(event) {
setText(event.target.value);
}
return (
<>
<p>{text}</p>
<input value={text} onChange={handleChange} />
</>
);
}
Checkbox#
<script>
let isAvailable = false;
</script>
<input id="is-available" type="checkbox" bind:checked={isAvailable} />
<label for="is-available">Is available</label>
import { useState } from 'react';
export default function IsAvailable() {
const [isAvailable, setIsAvailable] = useState(false);
function handleChange() {
setIsAvailable(!isAvailable);
}
return (
<>
<input id="is-available" type="checkbox" checked={isAvailable} onChange={handleChange} />
<label htmlFor="is-available">Is available</label>
</>
);
}
Radio#
<script>
let picked = 'red';
</script>
<div>Picked: {picked}</div>
<input id="blue-pill" bind:group={picked} type="radio" value="blue" />
<label for="blue-pill">Blue pill</label>
<input id="red-pill" bind:group={picked} type="radio" value="red" />
<label for="red-pill">Red pill</label>
import { useState } from 'react';
export default function PickPill() {
const [picked, setPicked] = useState('red');
function handleChange(event) {
setPicked(event.target.value);
}
return (
<>
<div>Picked: {picked}</div>
<input id="blue-pill" checked={picked === 'blue'} type="radio" value="blue" onChange={handleChange} />
<label htmlFor="blue-pill">Blue pill</label>
<input id="red-pill" checked={picked === 'red'} type="radio" value="red" onChange={handleChange} />
<label htmlFor="red-pill">Red pill</label>
</>
);
}
Select#
<script>
let selectedColorId = 2;
const colors = [
{ id: 1, text: 'red' },
{ id: 2, text: 'blue' },
{ id: 3, text: 'green' },
{ id: 4, text: 'gray', isDisabled: true },
];
</script>
<select bind:value={selectedColorId}>
{#each colors as color}
<option value={color.id} disabled={color.isDisabled}>
{color.text}
</option>
{/each}
</select>
import { useState } from 'react';
const colors = [
{ id: 1, text: 'red' },
{ id: 2, text: 'blue' },
{ id: 3, text: 'green' },
{ id: 4, text: 'gray', isDisabled: true },
];
export default function ColorSelect() {
const [selectedColorId, setSelectedColorId] = useState(2);
function handleChange(event) {
setSelectedColorId(event.target.value);
}
return (
<select value={selectedColorId} onChange={handleChange}>
{colors.map((color) => (
<option key={color.id} value={color.id} disabled={color.isDisabled}>
{color.text}
</option>
))}
</select>
);
}
Webapp features#
Fetch data#
<script>
import useFetchUsers from './useFetchUsers';
const { isLoading, error, data: users } = useFetchUsers();
</script>
{#if $isLoading}
<p>Fetching users...</p>
{:else if $error}
<p>An error occured while fetching users</p>
{:else if $users}
<ul>
{#each $users as user}
<li>
<img src={user.picture.thumbnail} alt="user" />
<p>
{user.name.first}
{user.name.last}
</p>
</li>
{/each}
</ul>
{/if}
import useFetchUsers from './useFetchUsers';
export default function App() {
const { isLoading, error, data: users } = useFetchUsers();
return (
<>
{isLoading ? (
<p>Fetching users...</p>
) : error ? (
<p>An error occured while fetching users</p>
) : (
users && (
<ul>
{users.map((user) => (
<li key={user.login.uuid}>
<img src={user.picture.thumbnail} alt="user" />
<p>
{user.name.first} {user.name.last}
</p>
</li>
))}
</ul>
)
)}
</>
);
}
Router link#
With
SvelteKit
<ul>
<li>
<a href="/"> Home </a>
</li>
<li>
<a href="/about"> About us </a>
</li>
</ul>
With
NextJS
import Link from 'next/link';
export default function Home() {
return (
<ul>
<li>
<Link href="/">
<a>Home</a>
</Link>
</li>
<li>
<Link href="/about">
<a>About us</a>
</Link>
</li>
</ul>
);
}
Routing#
With
SvelteKit
|-- routes/
|-- index.svelte // index page "/"
|-- about.svelte // about page "/about"
|-- __error.svelte // handle HTTP errors 404, 500,...
|-- __layout.svelte // global app layout
With
NextJS
|-- pages/
|-- index.js // index page "/"
|-- about.js // about page "/about"
|-- 404.js // handle error HTTP 404 page not found
|-- 500.js // handle error HTTP 500
|-- _app.js // global app layout
With
Remix
|-- root.jsx // global app layout
|-- routes/
|-- index.jsx // index page "/"
|-- about.jsx // about page "/about"
|-- $.jsx // fallback page
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK