<!DOCTYPE html> <html lang="en"> <head> <title>Redux basic example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <style> button { min-width: 70px; height: auto; font-size: 30px; } </style> <div> <p> Clicked: <span id="value">0</span> times <button id="increment">+</button> <button id="decrement">-</button> <button id="incrementIfOdd">Increment if odd</button> <button id="incrementAsync">Increment async</button> </p> </div> <script type="module"> import * as Redux from 'https://unpkg.com/redux@latest/dist/redux.browser.mjs' function counter(state, action) { if (typeof state === 'undefined') { return 0 } switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } } var store = Redux.createStore(counter) var valueEl = document.getElementById('value') function render() { valueEl.innerHTML = store.getState().toString() } render() store.subscribe(render) document.getElementById('increment') .addEventListener('click', function () { store.dispatch({ type: 'INCREMENT' }) }) document.getElementById('decrement') .addEventListener('click', function () { store.dispatch({ type: 'DECREMENT' }) }) document.getElementById('incrementIfOdd') .addEventListener('click', function () { if (store.getState() % 2 !== 0) { store.dispatch({ type: 'INCREMENT' }) } }) document.getElementById('incrementAsync') .addEventListener('click', function () { setTimeout(function () { store.dispatch({ type: 'INCREMENT' }) }, 1000) }) </script> <hr> <a href="https://github.com/reduxjs/redux/tree/master/examples/counter-vanilla">https://github.com/reduxjs/redux/tree/master/examples/counter-vanilla</a> <pre contenteditable id=code></pre> <script>fetch("").then(res => res.text()).then(res => code.textContent = res)</script> </body> </html>