React : Redux and React-React Sample
Redux and React-React | |
App.js | |
import React from “react”; import TodosContainer from ‘./Container/TodosContainer’ import CounterContainer from ‘./Container/CounterContainer’ import Todos from ‘./Components/Todos’ function App() { return( <div> <CounterContainer></CounterContainer> <TodosContainer></TodosContainer> </div> ) } export default App; |
Modules/Actions.js | |
import { INCREASE , DECREASE } from ‘./Types’ import { CHANGE_INPUT , INSERT , TOGGLE , REMOVE } from ‘./Types’ let id = 3; const doIncrease = () => { return { type : INCREASE , payload : 1 } } const doDecrease = () => { return { type : DECREASE, payload : -1 } } const doChangeInput = (input) =>{ return { type : CHANGE_INPUT, input : input } } const doInsert = (text) =>{ return { type : INSERT , todo : { id : id++ , text , done : false } } } const doToggle = (id) => { return { type : TOGGLE , id } } const doRemove = id => { return { type : REMOVE , id } } export { doIncrease , doDecrease} export { doChangeInput , doInsert , doToggle , doRemove } |
Modules/Reducer.js | |
import { INCREASE , DECREASE} from ‘./Types’ import { CHANGE_INPUT , INSERT , TOGGLE , REMOVE } from ‘./Types’ const counterInit = { number : 0 } function CounterReducer( state = counterInit , action) { console.log(‘CounterReducer:’ , state.number) switch(action.type) { case INCREASE : return { …state, number : state.number + action.payload } case DECREASE : return{ …state, number : state.number + action.payload } default : return state; } } const todosInit = { input : ”, todos : [ { id : 1 , text : ‘테스트 데이터1’ , done : true}, { id : 2 , text : ‘테스트 데이터2 ‘ , done : false}, ] } function TodosReducer(state = todosInit , action) { // console.log(‘TodosReducer:’ , state.todos[0].text) switch(action.type) { case CHANGE_INPUT : console.log(‘CHANGE_INPUT’ ,state) return { …state , input : action.input } case INSERT : console.log(‘INSERT’, action.todo) return { …state, todos : state.todos.concat(action.todo) } case TOGGLE : return { …state, todos : state.todos.map( i => { return i.id === action.id ? { …i , done : !i.done} : i }) } case REMOVE : return { …state, todos : state.todos.filter( i => i.id !== action.id) } default : return state } } export { CounterReducer , TodosReducer } |
Modules/Reducer.js | |
import { INCREASE , DECREASE} from ‘./Types’ import { CHANGE_INPUT , INSERT , TOGGLE , REMOVE } from ‘./Types’ const counterInit = { number : 0 } function CounterReducer( state = counterInit , action) { console.log(‘CounterReducer:’ , state.number) switch(action.type) { case INCREASE : return { …state, number : state.number + action.payload } case DECREASE : return{ …state, number : state.number + action.payload } default : return state; } } const todosInit = { input : ”, todos : [ { id : 1 , text : ‘테스트 데이터1’ , done : true}, { id : 2 , text : ‘테스트 데이터2 ‘ , done : false}, ] } function TodosReducer(state = todosInit , action) { // console.log(‘TodosReducer:’ , state.todos[0].text) switch(action.type) { case CHANGE_INPUT : console.log(‘CHANGE_INPUT’ ,state) return { …state , input : action.input } case INSERT : console.log(‘INSERT’, action.todo) return { …state, todos : state.todos.concat(action.todo) } case TOGGLE : return { …state, todos : state.todos.map( i => { return i.id === action.id ? { …i , done : !i.done} : i }) } case REMOVE : return { …state, todos : state.todos.filter( i => i.id !== action.id) } default : return state } } export { CounterReducer , TodosReducer } |
Modules/RootReducer.js | |
import {combineReducers} from ‘redux’ import { CounterReducer , TodosReducer } from ‘./Reducer’ const RootReducer = combineReducers({ counter : CounterReducer , todos : TodosReducer }) export default RootReducer; |
Modules/RootStore.js | |
import { createStore } from ‘redux’ import RootReducer from ‘./RootReducer’ const RootStore = createStore(RootReducer) export default RootStore; |
Modules/Types.js | |
const INCREASE = “INCREASE” const DECREASE = “DECREASE” const CHANGE_INPUT = “CHANGE_INPUT” const INSERT = “INSERT” const TOGGLE = “TOGGLE” const REMOVE = “REMOVE” export {INCREASE , DECREASE , CHANGE_INPUT , INSERT , TOGGLE , REMOVE} |
Container/CounterContainer.js | |
import Counter from ‘../Components/Counter’ import { doIncrease , doDecrease } from ‘../Modules/Actions’ import { connect } from ‘react-redux’ function CounterContainer(props){ return( <Counter number={props.number} onIncrease={props.onIncrease} onDecrease={props.onDecrease}></Counter> ) } const mapStateToProps = (state) => { return { number : state.counter.number } } /* const mapDispatchToProps = (dispatch) => { return { onIncrease : () => { dispatch(doIncrease()) } , onDecrease : () => { dispatch(doDecrease()) } } } */ const mapDispatchToProps = { onIncrease : doIncrease() , onDecrease : doDecrease() } export default connect(mapStateToProps,mapDispatchToProps)(CounterContainer); |
Container/TodosContainer.js | |
import React from ‘react’ import { connect } from ‘react-redux’ import { doChangeInput , doInsert , doToggle , doRemove } from ‘../Modules/Actions’ import Todos from ‘../Components/Todos’ constTodosContainer = ({input , todos , changeInput , insert , toggle , remove}) => { return( <Todos input={input} todos={todos} onChangeInput={changeInput} onInsert={insert} onToggle={toggle} onRemove={remove} ></Todos> ) } const mapStateToProps = (state) =>{ return { input : state.todos.input, todos : state.todos.todos } } const mapDispatchToProps = (dispatch) => { return { changeInput : (v) => dispatch(doChangeInput(v)), insert : (v) => dispatch(doInsert(v)), toggle : (v) => dispatch(doToggle(v)) , remove : (v) => dispatch(doRemove(v)) } } export default connect(mapStateToProps,mapDispatchToProps)(TodosContainer) |
Components/Counter.js | |
import React from ‘react’ import { doIncrease , doDecrease} from ‘../Modules/Actions’ import {connect} from ‘react-redux’ function Counter({number , onIncrease , onDecrease}){ return( <div> <h1>{number}</h1> <div> <button onClick={onIncrease}>+</button> <button onClick={onDecrease}>-</button> </div> </div> ) } const mapStateToProps = (state) => { return { number : state.counter.number } } const mapDispatchToProps = (dispatch) => { return{ onIncrease : () => dispatch(doIncrease()) , onDecrease : () => dispatch(doDecrease()) } } export default connect(mapStateToProps,mapDispatchToProps)(Counter); |
Components/Todos.js | |
import React from ‘react’ import {useRef} from ‘react’ const css = “cursor:pointer” function TodosItem({todo , onToggle , onRemove}) { return( <div style={{css}}onClick={()=>onToggle(todo.id)}> <input type=”checkbox” checked={todo.done} readOnly ></input> <span style={{ textDecoration: todo.done ? ‘line-through’ : ‘none’}}>{todo.text}</span> <button onClick={()=>onRemove(todo.id)}>삭제</button> </div> ) } function Todos({input , todos , onChangeInput , onInsert , onToggle , onRemove}) { const inputfocus = useRef(); const onSubmit = (e) => { e.preventDefault(); if (input !== “”) { onInsert(input) onChangeInput(“”) inputfocus.current.focus(); } } const onChange = (e) => { onChangeInput(e.target.value) } return( <div> <form onSubmit={onSubmit}> <input onChange={onChange} value={input} ref={inputfocus}></input> <button type=”submit”>등록하기</button> </form> <div> { todos.map( i => { return <TodosItem key={i.id} todo={i} onToggle={onToggle} onRemove={onRemove} ></TodosItem> }) } </div> </div> ) } export default Todos; |