rfce
함수형 컴포넌트를 rfce 네 글자로 react임포트와 파일이름으로 컴포넌트를 생성해줍니다.
vs code 확장 프로그램 ->es7 검색 후 ES7+ React/Redux/React-Native snippets 설치
jsx파일에 rfce를 입력 후 엔터를 치면 완성.
유니크한 키가 있어야 한다는 오류.
맵으로 돌릴 때는 코드 전체를 리턴하기 때문에 몇번째 div인지 확인이 불가능하다. 그래서 div안에 key라는 속성을 넣어야 한다.
key={todo.id}
투두앱 만들기[최종정리]
app.jsx
import React, { useState } from "react";
import { v4 as uuidv4 } from "uuid";
import "./App.css";
import Header from "./components/Header";
import Input from "./components/Input";
import TodoList from "./components/TodoList";
function App() {
//state : todo라는 객체를 여러개 가지고 있는 배열이다.
const [state, setState] = useState(stateList);
return (
<>
<Header>헤더</Header>
<main style={{ padding: "20px", background: "green" }}>
{/* 인풋을 만들어 입력하는 부분 */}
{/* 인풋태그2개와 버튼이 들어간다 */}
<Input setState={setState} />
{/* input태그를 에 setState를 넣어 input.jsx에서도 사용 가능하게 props로 내려준다*/}
{/* todolist를 출력하는 부분 */}
{/* 투두와 완료가 같으니 안에서 값만 제어하면 된다.props isActive와 state값을 넘겨준다. */}
<TodoList isActive={true} state={state} setState={setState} />
<TodoList isActive={false} state={state} setState={setState} />
</main>
<footer></footer>
</>
);
}
export default App;
const stateList = [
{
title: "제목",
content: "내용",
isDone: false,
id: uuidv4(),
},
{
title: "제목",
content: "내용",
isDone: true,
id: uuidv4(),
},
];
Header.jsx
import React from "react";
function Header({ children }) {
//얘를 app.jsx의 children으로 넘겨주기 때문에 ()안에 children값을 준다.(props)
return <header>{children}</header>;
}
export default Header;
Input.jsx
import React, { useState } from "react";
import { v4 as uuidv4 } from "uuid";
function Input({ setState }) {
// 제목과 내용에 대한 state를 가지고 있어야 한다.
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const handleSubmit = (event) => {
//페이지 갱신을 막기위해 onSubmit이 가지고 있는event를 받아 preventDefault해주면 갱신이 방지된다.
event.preventDefault();
//타이틀과 콘텐츠가 입력되지 않은 것이 있다면 alert를 출력해
//다만 handleSubmit함수의 기본 return동작때문에 오류가 발생해도 그냥 추가해버린다..
//그래서 title과content에 return을 넣는다.
if (!title) {
return alert("제목을 입력해주세요");
}
if (!content) {
return alert("내용을 입력해주세요");
}
const NewstateList = {
title: title,
content: content,
isDone: false,
id: uuidv4(),
};
//셋팅된 title과content를 state에 넣는 작업.이전값을 인자로 받는다!!!!
setState((prev) => {
//이전값은 가지고 있고 새로운값을 더해라.
return [...prev, NewstateList];
});
//useState를 통해서 값을 변경해줬을 때 변경방법은 set~~밖에 없으니 이것을 통해
//추가버튼시 input태그의 공백으로 바꿔준다.
//prev의 방법은 배열은 굉장히 용이하나 문자열은....그냥 그렇다...
setTitle("");
setContent("");
};
const handleTitleChange = (event) => {
setTitle(event.target.value);
};
const handleContentChange = (event) => {
setContent(event.target.value);
};
return (
<section>
<form onSubmit={handleSubmit}>
{/* 컴포넌트를 나눠서 상위 ->하위 컴포넌트로 props를 보내고 관리할 수 있도록
(prop를 보내는 대상이 state니까 그 하위 컴포넌트를 통해 set 등의 기능을 가진 컴포넌트를 만들것이다.)
추가 버튼을 누르면 리스트로 들어가게 한다. */}
제목 : <input value={title} onChange={handleTitleChange} />
내용 : <input value={content} onChange={handleContentChange} />
{/* input의 내용과 title,content는 같이 가야한다. 내용이 입력될 때마다 state가 갱신되야하니까 */}
<button>추가</button>
</form>
</section>
);
}
export default Input;
TodoList.jsx
import React from "react";
import Todo from "./Todo";
function TodoList({ state, setState, isActive }) {
//props로 state를 받아온다. 이후 맵함수를 통해 전체를 돌린다.
return (
//js문법이니 중괄호. app.jsx에서 todoList를 2개 출력인데 완료와 되지않은 것으로 나눠야하는데
//여기서 props 하나만 전달하면 될 것같다.
<div>
{/* 해야할 것과 완료된 것을 나눠야 하기 때문에 isActive를 통해 제어한다
isActive를 통해 투두에 있는 배열도 제어가 가능하다.*/}
<h4>{isActive === true ? "해야할 것" : "완료된 것"}</h4>
{state
//filter를 통해 해야할 것과 완료된 것을 구분해서 나눈다.여기의 todo는 state하나하나를 말한다.
.filter((todo) => todo.isDone === !isActive) //todo의 isDone이 isActive가 아니것만 나오게 한다.
.map((todo) => {
// 투두가 가지고 있는 타이틀.
return <Todo todo={todo} isActive={isActive} setState={setState} />;
})}
</div> //빈태그가 아닌 div로 설정해야 안의 내용을 css 제어 가능하다.>
);
}
export default TodoList;
Todo.jsx
import React from "react";
function Todo({ todo, isActive, setState }) {
const handleDeleteBttn = () => {
//삭제했던 게 없어지고 기존의 state가 갱신되야한다.그래서 setState를 써야한다.
//삭제하려는 id를 접근하여 삭제한다.
setState((prev) => prev.filter((List) => List.id !== todo.id));
//List가 가지고 있는 id가 todo가 가지고 있는 id랑 다르면 filter해라.일치하는id빼고 갱신.
};
const handleSwitchBttn = () => {
//삭제와 마찬가지로 setState를 통해 기존값으로 변경하고,isdone이 true,false왓다갓다하게
//이전값을 map을 통해서 prev에 있는 todo를 하나하나씩들어간다.컴포넌트 자체의 id와 비교해서 같으면
//내가 완료 버튼을 눌렀을 때 가리킨 컴포넌트와 일치하면 객체를 바꿔준다.
setState((prev) =>
prev.map((switchtodo) => {
//switchtodo가 가지고 있는게 저 투두리스트 통틀어 하난데 만약 첫번째 완료버튼을 누르면
//switchtodo.id가 첫번째 id를 가리키고 있는건데 구조분해 할당을 통해 안에 바뀔값만 다시 설정해주면 된다.
//isDone만 원래 가지고 있는 값이랑 반대로 넣어준다.그럼 새로운 값으로 리턴이 된다.아니면 원래 값으로 리턴한다.
//!가 부정의 뜻이니까 원래 것과 반대로 한다..라는 뜻같다.
if (switchtodo.id === todo.id) {
return { ...switchtodo, isDone: !switchtodo.isDone };
} else {
return switchtodo;
}
})
);
};
return (
//여기의 todo는 state의 투두 1개만 해당된다.
<div style={{ border: "2px solid blue" }} key={todo.id}>
<h4>{todo.title}</h4>
<p>{todo.content}</p>
<button onClick={handleSwitchBttn}>{isActive ? "완료" : "취소"}</button>
<button onClick={handleDeleteBttn}>삭제</button>
</div>
);
}
export default Todo;
후발대 5일차 정리..
후발대)React 투두앱을 배운 5일차 (tistory.com)
후발대)React 투두앱을 배운 5일차
변수가 바뀔 수 있도록 input이 change되게 한다. ?event인자가 없는데 어떻게 있나? 브라우저의 모든 이벤트는 액션이 있을 때 무조건 인자로 전달한다. console.log로 찍었을 때 targer안에 value가 있다.
jhee-web.tistory.com
'[내일배움캠프] > TIL' 카테고리의 다른 글
22.12.15)react숙련을 복습한 34일차 (0) | 2022.12.15 |
---|---|
22.12.14)후발대 과제영상 작업한 33일차 (1) | 2022.12.14 |
22.12.12)Redux를 배운 31일차 (0) | 2022.12.12 |
22.12.09)DB와 redux를 배운 30일차 (0) | 2022.12.09 |
22.12.08)React숙련 배운 29일차 (0) | 2022.12.08 |