Ukrainian Flag
Russia is still destroying lives. Click here to help.
Ukrainian Flag
me
Jakub Koleżyński
Blog Talks Apps
React with Svelte components

React with Svelte components

09.11.2023

Stuck in a React codebase? Longing for the new and shiny? Oh, do I have a treat for you!

You too can write Svelte components, right in your React app.

And the setup takes less then 5 minutes!

Foreshadowing 🧛

Prepare for your project to look like this:

	src
	├───components
	│   ├───todo-list.tsx
+	|   └───todo-list-item.svelte
	├───App.css
	├───App.tsx
	├───index.css
	├───main.tsx
	└───vite-env.d.ts

Setup

1. Add packages

npm i -D svelte
npm i -D @sveltejs/vite-plugin-svelte
npm i -D svelte-preprocess
npm i -D svelte-preprocess-react

2. Plug in the plugin

// ./vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// import stuff
import { svelte } from '@sveltejs/vite-plugin-svelte';
import sveltePreprocess from 'svelte-preprocess';
import preprocessReact from 'svelte-preprocess-react/preprocessReact';

export default defineConfig({
	plugins: [
		react(),
		// Use the plugin
		svelte({
			preprocess: [sveltePreprocess({ typescript: true }), preprocessReact()],
		}),
	],
});

Component crossplay!

Svelte in React:

In .tsx files, wrap Svelte components with reactify()

// ./src/component.tsx
import { reactify } from 'svelte-preprocess-react';
import Counter from './counter.svelte';

const SvelteCounter = reactify(Counter);

export function Component() {
	return <SvelteCounter />;
}

React in Svelte:

In .svelte files, prefix React component tags with react:

<!-- ./src/component.svelte -->
<script>
	import { Counter } from './counter.tsx';
</script>

<react:Counter />

If you're using typescript, you will encounter an unused import problem. This can be hotwired with his utility:

import { used } from 'svelte-preprocess-react';
used(Counter);

Svelte stores

The packages you already installed also include a handy useStore hook, that provides the current value of a store.

To change the value of a writable, use the set and update methods right on the store.

// ./src/counter.tsx
import { count } from './count-store';
import { useStore } from 'svelte-preprocess-react';

export const Counter = () => {
	const $count = useStore(count);

	return (
		<>
			<p>count is {$count}</p>
			<button onClick={() => count.update((x) => x + 1)}>increment</button>
		</>
	);
};

VSCode Svelte plugin gotcha

If your .tsx files report type errors on import from .svelte files, this setting in the official VSCode Svelte plugin helps:

// ./.vscode/settings.json
{
	"svelte.enable-ts-plugin": true
}

Happy hacking ୧(^ 〰 ^)୨




Back to list

Comments:

Sign In to comment

profile pic
MateuszPacek
2024-04-12 18:50

Wow, amazing content, keep going m8