Some applications only need a very minimal routing solution. This lesson will cover a practical example showing the router in use. We’ll build a simple search feature that accepts user input and then calls the github API. We’ll see how to access route parameters, how to manually & automatically navigate around, and finally how to handle un-matched path. https://github.com/developit/preact-router
Install:
npm install --save preact-router
Define routers:
import {h} from 'preact';
import { Router } from 'preact-router';
import Profile from './Profile';
import Home from './Home';
import Error from './Error';
export default function App() {
return (
<Router>
<Home path="/" />
<Profile path="/profile/:user"/>
<Error default/>
</Router>
);
}
Defailt Error router:
import {h} from 'preact';
import {route} from 'preact-router';
const back = (e) => {
route('/');
};
export default Error = () => (
<div>
<h2>Error!</h2>
<button onClick={e => back(e)}>Home</button>
</div>
);
Home: preact call route() function to navigate between components.
import { h } from 'preact';
import { route } from 'preact-router';
function search(query) {
route(`/profile/${encodeURIComponent(query)}`);
}
export default function Home() {
return (
<section>
<p>Enter a Github Username</p>
<input type="search"
placeholder="username"
onSearch={e => search(e.target.value)}
/>
</section>
);
}
Profile.js: Stateful component, fetching data:
import {h, Component} from 'preact';
import User from './User';
const config = {
url: 'https://api.github.com/users'
};
export default class Profile extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
user: null
};
}
componentDidMount() {
fetch(`${config.url}/${this.props.user}`)
.then(resp => resp.json())
.then(user => {
this.setState({
user,
loading: false
});
})
.catch(err => console.error(err));
}
render({user: username}, {loading, user: userState}) {
return (
<div class="app">
{loading
? <p>Fetching {username}'s profile</p>
: <User image={userState.avatar_url}
name={userState.name} />
}
</div>
);
}
}