Signals basically remove the need for using useState and useEffect to manage state. And with Signals, you don't even have to pass data through component props, similar to provide/inject from Vuejs.
The old way with useState and useEffect you can see on the old-way branch.
If you lazy to take a look between those 2 branches, here is the code comparison:
const BASE_URL = "https://pokeapi.co/api/v2/pokemon?limit=5&offset=";
const [pokemon, setPokemon] = useState({});
const [page, setPage] = useState(0);
useEffect(() => {
const fetchData = async () => {
const res = await fetch(BASE_URL + page * 5);
const data = await res.json();
setPokemon(data);
}
fetchData();
}, []);
const BASE_URL = "https://pokeapi.co/api/v2/pokemon?limit=5&offset=";
const pokemon = signal({});
const page = signal(0);
effect(async () => {
const res = await fetch(BASE_URL + page.value * 5);
const data = await res.json();
pokemon.value = data;
})
<div>
<button onClick={() => setPage(prev => prev - 1)}>Previous Page</button>
<button onClick={() => setPage(prev => prev + 1)}>Next Page</button>
<div>Current page: {page}</div>
</div>
<div>
<button onClick={() => page.value -= 1}>Previous Page</button>
<button onClick={() => page.value += 1}>Next Page</button>
<div>Current page: {page}</div>
</div>
Two points above have a quite similar things right?, but the main difference is, you actually can export the signals to be used on the other component, and it updated synchronously, example:
// main component
export const pokemon = signal({});
// ... the rest code for fetching
// other component:
import { pokemon } from "../App"
const Navbar = () => {
return (
<div>
This is Navbar | Total pokemon: {pokemon.value.count}
</div>
)
}
According to this issue: preactjs/signals#469. There is some problem, so you need to use computed like this:
const totalPokemon = computed(() => pokemon.value.count)
OR put import "@preact/signals-react/auto"
to the root of app.
By using Signals, you don't need to pass the data by the props like this:
<Navbar data={pokemon} setData={setPokemon} />
. You can easily import it and change the data everywhere. It could be a substitude for state management such as react reducer, redux, zustand, but every framework have their on speciality.