context/index.js
import React, { Component, createContext} from 'react'
const context = createContext()
const { Provider , Consumer: SimpleConsumer } = context
class TodoProvider extends Component {
state = {
idx: 0,
todos : [
{ idx: 0 , text:'test', checked : false }
]
}
actions = {
insert_todo : (value) => {
let new_idx = this.state.idx
new_idx++
this.setState({
idx: new_idx,
todos: [
...this.state.todos,
{
idx: new_idx,
text: value,
checked: false
}
]
})
},
delete_todo: (idx) => {
this.setState( {
...this.state,
todos: this.state.todos.filter((data) => data.idx !== idx)
})
},
toggle_todo: (idx) => {
this.setState( {
...this.state,
todos: this.state.todos.map( (data) => {
if(data.idx === idx){
data.checked = !data.checked
}
return data
})
})
}
}
render() {
const { state, actions } = this
const value = {state , actions }
return (
<Provider value={value}>
{this.props.children}
</Provider>
)
}
}
export {
TodoProvider, SimpleConsumer
}
App.js
import React from 'react';
import { TodoProvider } from './context/index'
import TodoList from './components/TodoList'
import TodoInsert from './components/TodoInsert'
import './App.css';
function App() {
return (
<TodoProvider>
<div className="App">
<TodoList/>
<TodoInsert/>
</div>
</TodoProvider>
);
}
export default App;
components/TodoInsert.js
import React, { Fragment, Component } from 'react'
import { SimpleConsumer } from '../context/index'
import styled from 'styled-components'
class Todo extends Component {
state = {
input : ''
}
handleChange = (e) => {
this.setState({
input: e.target.value
})
}
handleSave = (e) => {
this.props.setValue(this.state.input)
this.setState({input : ''})
}
handleUp = (e) => {
if(e.keyCode === 13){
this.handleSave()
}
}
render() {
return (
<Fragment>
<Input type="text" value={this.state.input}
onChange={this.handleChange}
onKeyDown={this.handleUp}>
</Input>
<button onClick={this.handleSave}>저장</button>
</Fragment>
)
}
}
const Input = styled.input`
margin-left: 20px;
width: 250px;
margin-right: 5px;
`
const SendsContainer = () => (
<SimpleConsumer>
{
({actions})=> (
<Todo setValue={actions.insert_todo}/>
)
}
</SimpleConsumer>
)
export default SendsContainer
components/TodoList.js
import React from 'react'
import { SimpleConsumer } from '../context/index'
import styled from 'styled-components'
const list = () => {
return (
<ul>
<SimpleConsumer>
{
({state, actions}) => {
return state.todos.map(t =>
<Li key={t.idx}>
<Span done={t.checked ? true : false} onClick={ (e) =>
actions.toggle_todo(t.idx)
}>{t.text}</Span>
<Button onClick={ (e) =>
actions.delete_todo(t.idx)
}>삭제</Button>
</Li>
)
}
}
</SimpleConsumer>
</ul>
)
}
const Li = styled.li`
width: 280px;
position: relative;
margin: 3px;
`
const Span = styled.span`
text-decoration : ${props => props.done ? "line-through" : "none"};
cursor: pointer;
`
const Button = styled.button`
position: absolute;
right:0;
`
export default list