{"id":17095574,"url":"https://github.com/slavahatnuke/actives-reactjs-todos-example","last_synced_at":"2026-05-03T16:32:48.981Z","repository":{"id":151749186,"uuid":"64334206","full_name":"slavahatnuke/actives-reactjs-todos-example","owner":"slavahatnuke","description":"Todo List - pure logic - pure views - (PL) \u003c-\u003e (PV) example","archived":false,"fork":false,"pushed_at":"2016-08-01T18:57:07.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-23T17:49:00.816Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slavahatnuke.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-27T18:57:13.000Z","updated_at":"2016-07-30T22:54:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"aa7fa507-51a1-4ec8-9d0d-86cfaacf5f66","html_url":"https://github.com/slavahatnuke/actives-reactjs-todos-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/slavahatnuke/actives-reactjs-todos-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavahatnuke%2Factives-reactjs-todos-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavahatnuke%2Factives-reactjs-todos-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavahatnuke%2Factives-reactjs-todos-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavahatnuke%2Factives-reactjs-todos-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slavahatnuke","download_url":"https://codeload.github.com/slavahatnuke/actives-reactjs-todos-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavahatnuke%2Factives-reactjs-todos-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32577122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T14:43:11.834Z","updated_at":"2026-05-03T16:32:48.964Z","avatar_url":"https://github.com/slavahatnuke.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Todo List - ReactJS Actives  example. \nThere is an example how to use `ReactJS` and `actives`.\n\n### How to start\n- `npm install`\n- `npm start`\n- `http://localhost:8080/` [http://localhost:8080/](http://localhost:8080/)\n\n### How does it look?\n`app.js`\n\n```javascript\nimport React from 'react';\nimport {render} from 'react-dom';\n\n// get app from the box\nimport box from './Todos/box';\n\n// and render\nrender(\u003cbox.TodoApp/\u003e, document.getElementById('app'));\n```\n\n### Views - pure views (PV)\nThere are examples:\n\n`Todos/Todo.js` [Todos/Todo.js](Todos/Todo.js)\n```javascript\nimport React from 'react';\n\nexport default () =\u003e ({todo, onToggle, onRemove}) =\u003e {\n    return \u003cdiv\u003e\n        \u003cspan\u003e{todo.title}\u003c/span\u003e\n        \u003cspan\u003e [{todo.status ? 'DONE' : 'WIP'}] \u003c/span\u003e\n        \u003cbutton onClick={() =\u003e onToggle(todo.id) }\u003etoggle\u003c/button\u003e\n        \u003cbutton onClick={() =\u003e onRemove(todo.id) }\u003eremove\u003c/button\u003e\n    \u003c/div\u003e;\n} \n```\n\n`Todos/TodoList.js` [Todos/TodoList.js](Todos/TodoList.js)\nIn this example we inject __Todo__\n\n```javascript\nimport React from 'react';\n\nexport default ({Todo}) =\u003e ({todos = []}) =\u003e {\n    return \u003cdiv\u003e\n        {todos.map(todo =\u003e\u003cTodo key={todo.id} todo={todo}/\u003e)}\n    \u003c/div\u003e;\n} \n```\n\n`Todos/TodoEditor.js` [Todos/TodoEditor.js](Todos/TodoEditor.js)\n\n```javascript\nimport React from 'react';\n\nexport default () =\u003e ({todo, onSave}) =\u003e {\n    let input;\n    let save = () =\u003e {\n        todo.title = input.value;\n        onSave(todo);\n        input.value = '';\n    };\n    return \u003cdiv\u003e\n        \u003cinput type=\"text\" placeholder=\"title\" ref={(el) =\u003e input = el}/\u003e\n        \u003cbutton onClick={save}\u003esave\u003c/button\u003e\n    \u003c/div\u003e;\n} \n```\n\n`Todos/TodoEditor.js` [Todos/TodoEditor.js](Todos/TodoEditor.js)\n\n```javascript\nimport React from 'react';\n\nexport default () =\u003e ({todo, onSave}) =\u003e {\n    let input;\n    let save = () =\u003e {\n        todo.title = input.value;\n        onSave(todo);\n        input.value = '';\n    };\n    return \u003cdiv\u003e\n        \u003cinput type=\"text\" placeholder=\"title\" ref={(el) =\u003e input = el}/\u003e\n        \u003cbutton onClick={save}\u003esave\u003c/button\u003e\n    \u003c/div\u003e;\n} \n```\n\n`Todos/TodoApp.js` [Todos/TodoApp.js](Todos/TodoApp.js)\nIn this example we inject __TodoEditor__ and __TodoList__\n```javascript\nimport React from 'react';\n\nexport default ({TodoEditor, TodoList}) =\u003e () =\u003e {\n    return \u003cdiv\u003e\n        \u003cTodoEditor\u003e\u003c/TodoEditor\u003e\n        \u003cTodoList\u003e\u003c/TodoList\u003e\n    \u003c/div\u003e;\n} \n```\n\n## Logic - pure logic (PL)\n`Todos/TodoService.js` [Todos/TodoService.js](Todos/TodoService.js)\n```javascript\nexport default class TodoService {\n    constructor() {\n        this.todos = [];\n        this.todo = null;\n        this.nextId = 1;\n    }\n\n    getTodo() {\n        return this.todo || {title: '', status: false};\n    }\n\n    save(todo) {\n        if (!todo.id) {\n            todo.id = this.nextId++;\n            this.add(todo);\n        }\n    }\n\n    getTodos() {\n        return this.todos;\n    }\n\n    add(todo) {\n        this.todos.push(todo)\n    }\n\n    remove(id) {\n        let todo = this.get(id);\n        todo \u0026\u0026 this.todos.splice(this.todos.indexOf(todo), 1)\n    }\n\n    toggle(id) {\n        let todo = this.get(id);\n        todo.status = !todo.status;\n    }\n\n    get(id) {\n        return this.todos.find((todo) =\u003e todo.id === id)\n    }\n}\n```\n\n\n## Connect Logic to Views. (PL) \u003c-\u003e (PV).\nFor this goal we use __box__. It allows to add service and make states for the views.\nThen we connect states to views.\n\n\n```javascript\n// actives box\nimport {Box} from 'actives';\n\n// function that connect state to view.\nimport connect from 'actives-react';\n\n// pure views.\nimport Todo from './Todo';\nimport TodoList from './TodoList';\nimport TodoEditor from './TodoEditor';\nimport TodoApp from './TodoApp';\nimport TodoService from './TodoService';\n\n// box, it registers service and makes states.\nlet box = new Box;\n\n// add service.\nbox.add('TodoService', TodoService);\n\n// it makes connected view with state. state + view = widget. TodoState is described below.\nbox.add('Todo', ({TodoState}) =\u003e connect(TodoState, Todo()));\n\n// make TodoList widget.\nbox.add('TodoList', ({Todo, TodoListState}) =\u003e connect(TodoListState, TodoList({Todo})));\n\n// make TodoEditor widget.\nbox.add('TodoEditor', ({TodoEditorState}) =\u003e connect(TodoEditorState, TodoEditor()));\n\n// it's just pure view, but it gets `TodoList` and `TodoEditor` widgets from the box.\nbox.add('TodoApp', TodoApp);\n\n// make state for TodoEditor widget.\nbox.connect('TodoEditorState', 'TodoService')\n    .state(({TodoService}) =\u003e {\n        return {\n            todo: TodoService.getTodo()\n        }\n    })\n    .actions(({TodoService}) =\u003e {\n        return {\n            onSave: (todo) =\u003e TodoService.save(todo)\n        }\n    });\n\n// make state for TodoList widget.\nbox.connect('TodoListState', 'TodoService')\n    .state(({TodoService}) =\u003e {\n        return {\n            todos: TodoService.getTodos()\n        }\n    });\n\n// make state for Todo widget.\nbox.connect('TodoState', 'TodoService')\n    .actions(({TodoService}) =\u003e {\n        return {\n            onRemove: (id) =\u003e TodoService.remove(id),\n            onToggle: (id) =\u003e TodoService.toggle(id)\n        }\n    });\n\nexport default box;\n```\n\n### Counter example\nIt an example with counter. [example](https://github.com/slavahatnuke/actives-reactjs-counter-example)\n\n### actives\nThe main idea of [actives](https://www.npmjs.com/package/actives)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslavahatnuke%2Factives-reactjs-todos-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslavahatnuke%2Factives-reactjs-todos-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslavahatnuke%2Factives-reactjs-todos-example/lists"}