3

Component Party

 2 years ago
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#

svelte Svelte
<script>
	let name = 'John';
</script>

<h1>Hello {name}</h1>

react React
import { useState } from 'react';

export default function Name() {
	const [name] = useState('John');

	return <h1>Hello {name}</h1>;
}

Update state#

svelte Svelte
<script>
	let name = 'John';
	name = 'Jane';
</script>

<h1>Hello {name}</h1>

react React
import { useState } from 'react';

export default function Name() {
	const [name, setName] = useState('John');
	setName('Jane');

	return <h1>Hello {name}</h1>;
}

Computed state#

svelte Svelte
<script>
	let count = 10;
	$: doubleCount = count * 2;
</script>

<div>{doubleCount}</div>

react React
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#

svelte Svelte
<h1>Hello world</h1>

react React
export default function HelloWorld() {
	return <h1>Hello world</h1>;
}

Styling#

svelte Svelte
<h1 class="title">I am red</h1>
<button style="font-size: 10rem;">I am a button</button>

<style>
	.title {
		color: red;
	}
</style>

react React
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#

svelte Svelte
<script>
	const colors = ['red', 'green', 'blue'];
</script>

<ul>
	{#each colors as color}
		<li>{color}</li>
	{/each}
</ul>

react React
export default function Colors() {
	const colors = ['red', 'green', 'blue'];
	return (
		<ul>
			{colors.map((color) => (
				<li key={color}>{color}</li>
			))}
		</ul>
	);
}

Event click#

svelte Svelte
<script>
	let count = 0;

	function incrementCount() {
		count++;
	}
</script>

<p>Counter: {count}</p>
<button on:click={incrementCount}>+1</button>

react React
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#

svelte Svelte
<script>
	import { onMount } from 'svelte';

	let inputElement;

	onMount(() => {
		inputElement.focus();
	});
</script>

<input bind:this={inputElement} />

react React
import { useEffect, useRef } from 'react';

export default function InputFocused() {
	const inputElement = useRef(null);

	useEffect(() => inputElement.current.focus(), []);

	return <input type="text" ref={inputElement} />;
}

Conditional#

svelte Svelte
<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>

react React
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#

svelte Svelte
<script>
	import { onMount } from 'svelte';
	let pageTitle = '';
	onMount(() => {
		pageTitle = document.title;
	});
</script>

<p>Page title is: {pageTitle}</p>

react React
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#

svelte Svelte
<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>

react React
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#

svelte Svelte
<script>
	import UserProfile from './UserProfile.svelte';
</script>

<UserProfile name="John" age={20} favouriteColors={['green', 'blue', 'red']} isAvailable />

react React
import UserProfile from './UserProfile.jsx';

export default function App() {
	return <UserProfile name="John" age={20} favouriteColors={['green', 'blue', 'red']} isAvailable />;
}

Emit to parent#

svelte Svelte
<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>

react React
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#

svelte Svelte
<script>
	import FunnyButton from './FunnyButton.svelte';
</script>

<FunnyButton>Click me !</FunnyButton>

react React
import FunnyButton from './FunnyButton.jsx';

export default function App() {
	return <FunnyButton>Click me !</FunnyButton>;
}

Slot fallback#

svelte Svelte
<script>
	import FunnyButton from './FunnyButton.svelte';
</script>

<FunnyButton />
<FunnyButton>I got content !</FunnyButton>

react React
import FunnyButton from './FunnyButton.jsx';

export default function App() {
	return (
		<>
			<FunnyButton />
			<FunnyButton>I got content !</FunnyButton>
		</>
	);
}

Form input#

Input text#

svelte Svelte
<script>
	let text = 'Hello World';
</script>

<p>{text}</p>
<input bind:value={text} />

react React
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#

svelte Svelte
<script>
	let isAvailable = false;
</script>

<input id="is-available" type="checkbox" bind:checked={isAvailable} />
<label for="is-available">Is available</label>

react React
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#

svelte Svelte
<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>

react React
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#

svelte Svelte
<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>

react React
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#

svelte Svelte
<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}

react React
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#

svelte Svelte
With SvelteKit
<ul>
  <li>
    <a href="/"> Home </a>
  </li>
  <li>
    <a href="/about"> About us </a>
  </li>
</ul>

react React
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#

svelte Svelte
With SvelteKit
|-- routes/
    |-- index.svelte // index page "/"
    |-- about.svelte // about page "/about"
    |-- __error.svelte // handle HTTP errors 404, 500,...
    |-- __layout.svelte // global app layout

react React
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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK