import {createEvent, createStore, createEffect, restore, combine, sample} from 'effector'
import {useStore, useList} from 'effector-react'
const submit = createEvent()
const submitted = createEvent()
const completed = createEvent()
const changed = createEvent()
const removed = createEvent()
const validate = createEffect(([todo, todos]) => {
if (todos.some(item => item.text === todo))
throw 'This todo is already on the list'
if (!todo.trim().length) throw 'Required field'
const $todo = restore(changed, '').reset(submitted)
const $error = restore(validate.failData, '').reset(changed)
const $todos = createStore([])
.on(submitted, (prev, next) => [...prev, {text: next, completed: false}])
.on(completed, (state, index) => state.map((item, i) => ({
completed: index === i ? !item.completed : item.completed,
.on(removed, (state, index) => state.filter((_, i) => i !== index))
submit.watch(e => e.preventDefault())
const tasks = useStore($todos)
const todo = useStore($todo)
const error = useStore($error)
const list = useList($todos, (item, index) => (
<li style={{textDecoration: item.completed ? 'line-through' : ''}}>
onChange={() => completed(index)}
<button type="button" onClick={() => removed(index)} className="delete">
onChange={e => changed(e.target.value)}
<button type="submit" onClick={submit} className="submit">
{error && <div className="error">{error}</div>}
<ul style={{listStyle: 'none'}}>{list}</ul>
ReactDOM.render(<App />, document.getElementById('root'))