-
Notifications
You must be signed in to change notification settings - Fork 16
Tutorial
Let's create a simple application which represents a sorted list of users with ability to add and remove users from it.
First of all we need to figure out how to decompose our application to the components. We'll use the following structure:
App
|-- UserList
| `-- UserListItem
`-- NewUser
Then let's import required parts from vidom module.
import { Component, mount } from 'vidom';
Our top component App
is a stateful component which will be responsible for the maintenance of the state of our application: a list of users represented by a regular array. In turn each user is a plain object with id
and login
fields.
We'll support two operations: adding a new user and removing existing one.
class App extends Component {
// store empty array as initial list of users
onInit() {
this.setState({ users : [] });
}
// onRender() hook is called when the component needs to be rendered.
onRender() {
const { users } = this.state;
return (
<div class="app">
<NewUser onAdd={ login => this.onAddUser(login) }/>
<UserList list={ users } onRemove={ id => this.onRemoveUser(id) }/>
</div>
);
}
onAddUser(login) {
// Just adding a new user to the array and resorting it.
this.setState({
users : this.state.users
.concat({ id : generateId(), login })
.sort((a, b) => a.login > b.login)
});
}
onRemoveUser(id) {
// Just removing a user from the array using "id".
this.setState({
users : this.state.users.filter(item => item.id !== id)
});
}
}
In onAddUser
we're using generateId()
function so let's define it:
let counter = 0;
function generateId() {
return counter++;
}
The next component UserList
is very simple, it just renders wrapping <ul>
and creates corresponding nodes for each user.
class UserList extends Component {
onRender() {
const { list, onRemove } = this.attrs;
return (
<ul>
{
list.map(user =>
<UserListItem
key={ user.id }
user={ user }
onRemove={ onRemove }
/>
)
}
</ul>
);
}
}
UserListItem
renders user's login and button to remove user from the list by click.
class UserListItem extends Component {
onRender() {
const { user, onRemove } = this.attrs;
return (
<li>
<span>{ user.login }</span>
<button onClick={ () => onRemove(user.id) }>remove</button>
</li>
);
}
}
class NewUser extends Component {
onInit() {
this.setState({ login : '' });
}
onRender() {
const { login } = this.state;
return (
<input
placeholder="enter new login"
value={ login }
onChange={ e => this.onInputChange(e) }
onKeyUp={ e => this.onInputKeyUp(e) }
/>
);
}
onInputChange(e) {
this.setState({ login : e.target.value });
}
onInputKeyUp(e) {
if(e.nativeEvent.keyCode === 13) {
const value = e.target.value.trim();
if(value) {
this.setState({ login : '' });
this.attrs.onAdd(value);
}
}
}
}
And the final touch — mounting our application to the DOM:
mount(document.body, <App/>);