웹/react

나도 만들어 보자 toodolist (3)

allblack 2020. 5. 10. 17:22
반응형

잡설

너무 힘들다 2개를 하루 안에 쓰니...

 

바로 ㄱㄱ

 

 

 

Fotter 기능 구현하기

기능을 설명하자면

all //모든 일정을 보이게 함
clear //클리어한 일정만 보이게 함
active //클리어하지 않은 일정만 보이게 함
clear //completed 모든 일정 제거

 

cntrolList.jsx

 ...
  useEffect(()=>{
        showListSet("all"); //시작하자마자 적용 시키기 위해
    },[]);//이렇게 사용하면 처음 랜더링 될때만 실행됨
 var length=0;//리스트길이 저장 이유는 밑에서 설명
 const [nowstate,setnowstate]=useState("all");
 list=ListDatas.map((info)=>{if(info.show)++length; return<List key={info.id} state={info}></List>});
...//리스트 길이 측정을 위해 일부분을 수정했습니다.
function showListSet(showData){

        switch(showData){//switch 구문은 아시죠!!
            case "all":{
                SetListDatas(ListDatas.map((info)=>!info.show ? ({...info,show:true}) : info));
                //보이지 않게 설정되있는 값들을 보이게 수정합니다.
                setnowstate("all");
                break;
            }
            case "clear":{
                SetListDatas(ListDatas.map((info)=>info.clear ? ({...info,show:true}) : ({...info,show:false})));
                //clear 된 목록만 보이도록 수정합니다.
                setnowstate("clear");
                break;
            }
            case "active":{
                SetListDatas(ListDatas.map((info)=>!info.clear ? ({...info,show:true}) : ({...info,show:false})));
                //clear되지 않은 목록만 보이도록 수정합니다.
                setnowstate("active");
                break;
            }
            case "allclear":{
            //목록제거
                SetListDatas([]);
                break;
            }
        }
    }
    
    ...
    //fotter에서 사용하도록 함수를 보내줍니다.
	<Fotter leight={length} nowstate={nowstate} showListSet={showListSet}></Fotter>

이 3 부분들을 수정해 주세요!

 

Fotter.jsx

import React from 'react';
import styled from 'styled-components';

const Fotters =styled.div`
    display:${(props)=>props.show ? 'block' :"none"};//list leight가 0일 경우 안보이게
`;

const Contents=styled.div`
    border: ${(props)=>props.nowstate ? "solid 1px pink" : "none"};//클릭시 border생성
&:hover{
        border:solid 1px pink;//호버시에 vorder생성 
    }
`;

function Fotter(props) {
    var all,clear,active=false;
    
    switch(props.nowstate){
        case "all":{
            all=true;
            break;
        }
        case "clear":{
            clear=true;
            break;
        }
        case "active":{
            active=true;
            break;
        }
    }
    return (
        <Fotters show={props.leight}>
            <div>{props.leight} items left</div>
            <Contents nowstate={all} onClick={()=>props.showListSet("all")}>all</Contents>
            <Contents nowstate={clear} onClick={()=>props.showListSet("clear")}>clear</Contents>
            <Contents nowstate={active} onClick={()=>props.showListSet("active")}>active</Contents>
            <Contents onClick={()=>props.showListSet("allclear")}>clear completed</Contents>
        </Fotters>
    );
}

export default Fotter;

 

이제 마지막으로 List.jsx를 수정해주세요!

 

List.jsx

import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

List.propTypes = {
    state:PropTypes.object
};

const Lists =styled.div`
    display:${(props)=>props.show ? 'block' :"none"};
    //controlList에서 설정한 함수는 이값을 변경한것입니다. 그래서 작동을 안했죠!
`;

function List(props) {
    const state = props.state;
    return (
        <Lists show={state.show}>//show값 보내기
            {state.text}
            {state.day}
        </Lists>
    );
}

export default List;

 

결과

처음
hover 했을때
클릭했을때

달력 기능 구현하기!

 

 

달력 기능을 구현하기 위해서

 

일부 구조를 변경해야 합니다.

 

App.jsx

...
import Clalendar from './components/Clalendar';
...

function App() {
  var date=new Date();
  const [Month,setMonth]=useState(date.getMonth()+1);
  const [Day,setDay]=useState(date.getDate());

  function SetDays(time){
      setMonth(time.getMonth()+1);//날짜를 누를 때 월과일을 가져옵니다.
      setDay(time.getDate());
  }
  
  return (
    <div>
      ...
      //controlList.jsx에 있던 clalendar를 App로 이동 시켰습니다.
      <Clalendar setDays={SetDays}></Clalendar>
      //clalendar가 사용할수 있도록 함수를 props로 보내줍니다.
      <ControlList Month={Month} Days={Day}></ControlList>
      //변경된 달과 일의 값을 보내줍니다.
    </div>
  );
}

Clalendar.jsx

function Clalendar(props) {
	...
    return (
        <Calendar
          className={"calender"}
          onChange={onchange}
          onClickDay={props.setDays} //여기에 추가해주면 됩니다.
          value={Dated}/>
    );
}

ControlList.jsx

function ControlList(props) {
	var days=props.Days;
    var Month=props.Month;
    const [nowstate,setnowstate]=useState("all");
    ...
    useEffect(()=>{
        showListSet(nowstate);
    },[days]);//days값이 변경될 때마다 실행
    
     const [ListDatas,SetListDatas] = useState([{
        id:0,
        text:"일하기 싫당",
        clear:false,
        show:true,
        month:5,  //원래 day:"5/5"이렇게 되있던걸 달과 일로 분리시켰습니다.
        day:3
    },
    ...
    
    /*leight증가 구문의 조건이 추가 되었습니다. 
    보이는게 없어도 해당요일에 일정이 있다면 있다고 표시를 해주기 위해서*/
     list=ListDatas.map((info)=>{if(info.show || (info.month==Month && info.day==days))++length; return<List key={info.id} state={info}></List>});
     
     function Addlist(event){
        ...
        //달과 일로 분리했기때문에 addlist추가 구문도 수정 되었습니다.
        SetListDatas(ListDatas.concat({id:id++,text:value,clear:false,show:true,month:Month,day:days}));
    }
    
    function showListSet(showData){
    //조건이 수정 추가 되었습니다.
        switch(showData){
            case "all":{
                SetListDatas(ListDatas.map((info)=>info.month==Month && info.day==days ? ({...info,show:true}) : ({...info,show:false})));
                setnowstate("all");
                break;
            }
            case "clear":{
                SetListDatas(ListDatas.map((info)=>info.clear && info.month==Month && info.day==days ? ({...info,show:true}) : ({...info,show:false})));
                setnowstate("clear");
                break;
            }
            case "active":{
                SetListDatas(ListDatas.map((info)=>!info.clear && info.month==Month && info.day==days ? ({...info,show:true}) : ({...info,show:false})));
                setnowstate("active");
                break;
            }
            case "allclear":{
                SetListDatas([]);
                break;
            }
        }
    }
}

 

 

 

 

clear, delect 기능 구현하기

원래 이거를 추가 다음에 해야 했는데... 마지막에 하게 됐네요!

 

ControlList에 2 함수를 추가해 주세요

function clearlist(id){
        SetListDatas(ListDatas.map((info)=>info.id==id ? ({...info,clear:!info.clear}) : info));    
        //id로 원하는 data를 찾은 다음에 맞으면 clear를 반전 시킴
    }

    function deletelist(id){
        SetListDatas(ListDatas.filter((element) =>{return element.id!==id}));
        //id값이 같으면 제거
    }
    //함수 props로 전달
    list=ListDatas.map((info)=>{if(info.show || (info.month==Month && info.day==days))++length; return<List key={info.id} state={info} clearlist={clearlist} deletelist={deletelist}></List>}); 

 

List.jsx

const Lists =styled.div`
    display:${(props)=>props.show ? 'block' :"none"};
    text-decoration:${(props)=> props.clear ? "line-through" : "none"};//추가
`;

<Lists show={state.show} clear={state.clear} onClick={()=>props.clearlist(state.id)} onDoubleClick={()=>props.deletelist(state.id)}>

 

결과

clear
delect

download 구현하기

 

text파일로 받아서 보는 게 편할 것 같아서 txt 파일로 저장해 보겠습니다.

 

 

ControlList.jsx

function Download(){
        var value=ListDatas.map((info)=>{return info.text+info.month+"/"+info.day});
        //할일과 날짜정보를 가져옵니다.
        var element = document.createElement('a'); 
        //a태그를 만듭니다.
        element.setAttribute('href', 'data:text/plain;charset=utf-8,'+ encodeURIComponent(value.join('\n'))); 
        href에 href로 data를 저장합니다.
        element.download="Todos.txt";
        //다운로드할 파일 이름고 형식을 설정합니다.
        element.click();
        //강제로 클릭이밴트를 작동시켜서 다운로드 합니다!
    }
<Getlist Addlist={Addlist} Download={Download}></Getlist>
getlist에 download함수를 보냅니다.
function Getlist(props) {
    return (
        <div>
            <input type="text" placeholder="what needs to be done?" onKeyUp={props.Addlist}/>
            <button onClick={props.Download}>download</button>//함수를 수정합니다.
        </div>
    );
}

결과

이 정도 하면 간단한 todolist가 완성되었습니다.

 

 

 

 

https://github.com/famous0811/Todos

 

famous0811/Todos

블로그 자료. Contribute to famous0811/Todos development by creating an account on GitHub.

github.com

github에 올려놨습니다.

 

하다가 설명이 이상하다던가 모르겠으면 가서 확인해 보시는 것도 좋을 것 같습니다.

 

감사합니다!

반응형