끄적끄적

[React+Redux]간단하게 만들어보는 TodoList(2) 본문

React

[React+Redux]간단하게 만들어보는 TodoList(2)

2020. 11. 27. 02:55

이제 컴포넌트들을 작성할 시간입니다! 

 

 

4. App.js 

루트 컴포넌트로 MakeTodo와 Todo 컴포넌트를 return 해줍니다.

// App.js

import React from 'react';
import MakeTodo from './MakeTodo';
import Todo from './Todo';

function App(props){
    return(
        <>
            <MakeTodo />  		// 할일을 적을 수 있는 컴포넌트
            <Todo />			// 할일을 보여주는 컴포넌트
        </>
    )
}

export default App;

 

 

5. MakeTodo.js

// MakeTodo.js

import React, {useState} from 'react';
import { connect } from 'react-redux';

function MakeTodo(props){
    const [item, setItem] = useState('');
    const handleChange = e => {
        setItem(e.target.value);
    }

    return(
        <>
            <input type="text" value={item} onChange={handleChange}></input>
            <button onClick={()=>{
                props.AddTodo(item); ……………①
                setItem('');
            }}>Submit</button>
        </>
    )
}

const mapDispatchToProps = dispatch => {   ……………②
    return {
        AddTodo: (content) => dispatch({type : 'ADD', content}),
        DeleteTodo: (id) => dispatch({type: 'DELETE', id})
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(MakeTodo); ……………③

① click시 item을 매개변수로 갖는 AddTodo를 호출해 store를 업데이트합니다.

store에 접근한 컴포넌트가 store의 상태를 바꾸기 위해 dispatch를 사용할수 있게 만들어준다.

③ Provider 아래의 컴포넌트들이 store에 접근하여 이용할 수 있도록 연결해준다.

 

 

6. Todo.js

//Todo.js

import React from 'react';
import { connect } from 'react-redux';
import TodoItem from './TodoItem';

function Todo(props) {

    return (
        <>
            {props.ReduxData.todos.map((data, index) => {
                return (
                   <TodoItem key={index} id={index} cont={data} />
                )
            })}
        </>
    )
}

const mapStateToProps = state => ({ ……………①
    ReduxData: state
})

export default connect(mapStateToProps)(Todo);

① store의 값을 ReduxData라는 이름으로 가져와 사용할수 있도록 한다.

 

 

7. TodoItem.js

투두리스트의 아이템인 컴포넌트입니다.

수정과 삭제를 할 수 있는 button을 갖고 수정을 클릭할시 새로운 div의 display를 바꿔 바꿀 수 있는 창을 만들어줍니다.

//TodoItem.js

import React, {useState} from 'react';
import { connect } from 'react-redux';
function TodoItem(props){

    const [newValue, setnewValue] = useState('');
    const [updateDP, setupdateDP] = useState('none');

    const handleChange = e => {
        setnewValue(e.target.value);
    }

    return(
        <div key={props.id}>
        <p id={props.id}> {props.cont} </p>
        <button id={props.id} onClick={()=> props.DeleteTodo(props.id)}>삭제</button>
        <button id={props.id} onClick={()=> setupdateDP('block')}>수정</button>
        <div style={{display: updateDP}}>
            <input value={newValue} placeholder="새로운 값 입력하세요." onChange={handleChange} />
            <button onClick={()=> {
                props.UpdateTodo(props.id, newValue);
                setupdateDP('none');
                setnewValue('');
            }}>수정완료</button>
            
        </div>
    </div>
    )
}


const mapStateToProps = state => ({
    ReduxData: state
})


function mapDispatchToProps(dispatch) {
    return {
        DeleteTodo: (id) => dispatch({type:'DELETE', id}),
        UpdateTodo: (id, content) => dispatch({type:'UPDATE', id, content})
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoItem);

 

 

이렇게 완성되었습니다.

실행시 모습

css를 하나도 작성하지 않아 보기에 흉할수 있지만 기능은 이상없이 작동하는 것을 확인할 수 있습니다.

규모가 있는 프로젝트에서 Redux의 store 데이터를 관리할 때 어떠한 자료구조들을 언제 사용하느냐도 중요한 문제일 것 같네요. 

Comments