:scripts: https://unpkg.com/react@16/umd/react.development.js|https://unpkg.com/react-dom@16/umd/react-dom.development.js|js/2018/11/react.js
Writing JS posts with JBake : React JS
Intro
In this second entry about adding JS programming entries to JBake posts I’ve included a typical React TODO item example
The JS example I’m using here is just a quick draft just to show how to include JS and CSS code in a post entry. Don’t take it too seriosly. |
Add required resources
To be able to work with react, and load the example script, I need to add the scripts
attribute in the post header:
Basically, I’ve included the react
, react-dom
libraries at the
header of the document, and then the example dependency inside the
blog project’s assets js/2018/11/react.js
. If I would like to add a
custom css, you can add as well a css
entry in the post header:
:css: css/2018/11/react.css
No JSX when using plain JS
Because JSX can’t be included through a `<script/>' import, I had to create a helper function to create new elements.
const e = React.createElement;
TodoPanel
class TodoPanel extends React.Component {
constructor(props) { (1)
super(props);
this.state = {
task: '',
tasks: []
};
}
handleChange (e) { (2)
this.setState({task: e.target.value})
}
addItem () { (3)
this.setState({
tasks: [...this.state.tasks, this.state.task],
task: ''
})
}
deleteItem (item) { (4)
this.setState({tasks: this.state.tasks.filter(x => x !== item)})
}
render() { (5)
return e('div', {id: 'todo'},
e('input', {type: 'text', onChange: (ev) => this.handleChange(ev), value: this.state.task}),
e('button', {onClick: () => this.addItem() }, 'Add'),
e(TodoItems, {tasks: this.state.tasks, delete: (item) => this.deleteItem(item)})
);
}
}
1 | Create default state |
2 | Sets which is the current item to add |
3 | Adds the current item to the tasks list |
4 | Deletes the clicked item from the tasks list |
5 | renders the tasks panel |
Creating items
The TodoItems
component represents the tasks list. It only renders
an ul
elements containing as many items as tasks found in the task
list.
class TodoItems extends React.Component {
createTask (item) {
return e(TodoItem, {key: item, delete: this.props.delete, item: item}, null)
}
render () {
return e('ul', {key: 'items', className: 'items'}, this.props.tasks.map(x => this.createTask(x)))
}
}
Every item of the task list is built using the TodoItem
component
class TodoItem extends React.Component {
render () {
const { item } = this.props
const itemSpan = e('p', {key: `item-p-${item}`}, item)
const deleteButton = e('button',
{value: 'delete', key: `item-delete-${item}`, onClick: () => this.props.delete(item)},
'Delete')
return e('li', {key: item},
e('span', {className: 'item'}, [itemSpan, deleteButton]))
}
}
Render example
Finally, in order to render the TodoPanel
in this document we need
to link the component with an available dom element.
const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(TodoPanel), domContainer);
Result
It seems easy to add simple vanilla JS examples to a post. However trying to create more complex examples would require a proper build tool such as plain npm scripts or webpack.