app.js
const [todos, setTodos] = useState([
{
id: 1,
text: '리액트의 기초 알아보기',
checked: true,
},
{
id: 2,
text: '컴포넌트 스타일링 해보기',
checked: true,
},
{
id: 3,
text: '일정 관리 앱 만들어 보기',
checked: false,
},
]);
// 일정을 배열에 담아주었다.
{/* todos를 TodoList에서 쓰기위해 porps로 전달 */}
<TodoList todos={todos}></TodoList>
TodoList.js
// 부모 컴포넌트에서 받은 todos를 사용
const TodoList = ({ todos }) => {
return (
<TodoListBox>
{todos.map((todo) => (
<TodoListItem todo={todo} key={todo.id} />
// props로 받아온 todos를 map함수를 이용해서 TodoListItem 으로 보내준다.
// 객체를 통재로 props로 전달
))}
TodoListItem.js
import cn from 'classnames';
: 조건부 스타일링을 위해 classname이라는 것을 사용한다.
const TodoListItem = ({ todo }) => {
const { text, checked } = todo;
// todo의 text와 checked값을 구조분해할당해서 가져와서 사용
return (
<TodoListItemBox>
<div className={cn('checkbox', { checked })}>
{checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
{/* checked가 참이면 참 값을 , 거짓이면 거짓값을 보여준다. */}
<div>{text}</div>
</div>
<div>
<MdRemoveCircleOutline />
</div>
</TodoListItemBox>
);
};
TodoInsert.js
value로 상태관리 하기
const TodoInsert = () => {
const [value, setValue] = useState('');
// input에 입력하는 값을 관리하는 value를 만들어주었다
const onChange = useCallback((e) => {
setValue(e.target.value);
}, []);
// 추가로 input에 넣어줄 함수를 만들어줌
// usecallback -> 컴포넌트가 리렌더링될때마다 함수를 새로 만드는 것이 아니라
// 한 번 함수를 만들고 재사용할 수 있게해준다.
return (
<Formbox>
<input
placeholder="할 일을 입력하세요"
value={value}
onChange={onChange}
></input>
{/* value값과 onchange함수를 주었다. */}
<button type="sumit">
<MdAdd />
</button>
</Formbox>
);
};
export default TodoInsert;
App.js
const nextId = useRef(4);
// 객체가 새로 생겨서 새로 id 값이 필요하니끼
// ref를 사용하여 변수를 담았다.
// usestate가 아니라 useRef담은 것은
// id값은 렌더링되는 정보가 아니기 때문
// 함수의 성능을 아낄 수 있도록, useCallback으로 감싸주었다.
const onInsert = useCallback(
(text) => {
const todo = {
id: nextId.current,
text,
checked: false,
};
setTodos(todos.concat(todo));
nextId.current += 1;
},
[todos],
);
return (
<MainBox>
<TodoTemplate>
<TodoInsert onInsert={onInsert}></TodoInsert>
{/* onInsert함수를 TodoInsert에서 사용하기위해 porps로 전달 */}
<TodoList todos={todos}></TodoList>
{/* todos를 TodoList에서 쓰기위해 porps로 전달 */}
</TodoTemplate>
</MainBox>
);
}
export default App;
버튼을 클릭하면 이벤트가 발생하도록한다.
App.js에서 받아온 onInsert함수를 value값에 파라미터로 넣어 호출
TodoInsert.js
const TodoInsert = ({ onInsert }) => {
const [value, setValue] = useState('');
// input에 입력하는 값을 관리하는 value를 만들어주었다
const onChange = useCallback((e) => {
setValue(e.target.value);
}, []);
// 추가로 input에 넣어줄 함수를 만들어줌
// usecallback -> 컴포넌트가 리렌더링될때마다 함수를 새로 만드는 것이 아니라
// 한 번 함수를 만들고 재사용할 수 있게해준다.
const onSubmit = useCallback(
(e) => {
onInsert(value);
setValue(''); // value 값 초기화
// form의 submit 버튼을 눌렀을때 새로고침 이 발생하니까
// 그래서 방지하기 위해 아래 함수를 호출
e.preventDefault();
},
[onInsert, value],
);
return (
<Formbox onSubmit={onSubmit}>
<input
placeholder="할 일을 입력하세요"
value={value}
onChange={onChange}
></input>
{/* value값과 onchange함수를 주었다. */}
{/* input에 입력된 값이 onInsert함수에 의해
배열에 새로운 객체로 들어가고, 들어가게 되면 setValue로
input창이 빈칸이 된다. */}
<button type="submit">
{/* submit는 버튼+enter키로도 작동하고, click 이벤트는
클릭 할때만 작동한다. */}
<MdAdd />
</button>
</Formbox>
);
};
export default TodoInsert;
App.js
const onRemove = useCallback((id) => {
setTodos(todos.filter((todo) => todo.id !== id));
},[todos]);
return (
<MainBox>
<TodoTemplate>
<TodoInsert onInsert={onInsert}></TodoInsert>
{/* onInsert함수를 TodoInsert에서 사용하기위해 porps로 전달 */}
<TodoList todos={todos} onRemove={onRemove}></TodoList>
{/* todos를 TodoList에서 쓰기위해 porps로 전달 */}
{/* onInsert함수를 TodoListItem에서 사용하기 위해 일단 TodoLIst로 porps로 전달 */}
</TodoTemplate>
</MainBox>
);
}
TodoList.js
우리가 써야할 곳은 TodoListItem이기 때문에 한번 더 props로 내려준다.
const TodoList = ({ todos , onRemove}) => {
return (
<TodoListBox>
{todos.map((todo) => (
<TodoListItem todo={todo} key={todo.id} onRemove={onRemove} />
// props로 받아온 todos를 map함수를 이용해서 TodoListItem 으로 보내준다.
// 객체를 통재로 props로 전달
))}
</TodoListBox>
);
};
TodoListItem.js
const TodoListItem = ({ todo, onRemove }) => {
const { id, text, checked } = todo;
// todo의 text와 checked값을 구조분해할당해서 가져와서 사용
// onRemove함수에서 id값이 필요하니까 또 가져와서 사용한다.
return (
<TodoListItemBox>
<div className={cn('checkbox', { checked })}>
{checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
{/* checked가 참이면 참 값을 , 거짓이면 거짓값을 보여준다. */}
<div>{text}</div>
</div>
<div
onClick={() => {
onRemove(id);
}}
>
{/* const onRemove = useCallback((id) => {
setTodos(todos.filter((todo) => todo.id !== id));
},[todos]);
클릭을 하게 되면 id값이 인자로 들억사서 일치하게되어
해당 클릭값부분만 삭제된다*/}
<MdRemoveCircleOutline />
</div>
</TodoListItemBox>
);
};
export default TodoListItem;
-삭제기능과 비슷
App.js
const onToggle = useCallback(
(id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, check: !todo.checked } : todo,
),
);
},
[todos],
);
return (
<MainBox>
<TodoTemplate>
<TodoInsert onInsert={onInsert}></TodoInsert>
{/* onInsert함수를 TodoInsert에서 사용하기위해 porps로 전달 */}
<TodoList todos={todos} onRemove={onRemove} onToggle={onToggle}></TodoList>
{/* todos를 TodoList에서 쓰기위해 porps로 전달 */}
{/* onInsert함수를 TodoList에서 사용하기 위해 porps로 전달 */}
{/* onInsert함수와 똑같이 onToggle함수를 TodoList에서 사용하기 위해 porps로 전달 */}
</TodoTemplate>
</MainBox>
);
Todolist.js
const TodoList = ({ todos, onRemove, onToggle }) => {
return (
<TodoListBox>
{todos.map((todo) => (
<TodoListItem
todo={todo}
key={todo.id}
onRemove={onRemove}
onToggle={onToggle}
/>
// props로 받아온 todos를 map함수를 이용해서 TodoListItem 으로 보내준다.
// 객체를 통째로 props로 전달
))}
</TodoListBox>
TodoListItem.js
const TodoListItem = ({ todo, onRemove, onToggle }) => {
const { id, text, checked } = todo;
// todo의 text와 checked값을 구조분해할당해서 가져와서 사용
// onRemove함수에서 id값이 필요하니까 또 가져와서 사용한다.
return (
<TodoListItemBox>
<div className={cn('checkbox', { checked })} onClick={() => onToggle(id)}>
{checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
{/* checked가 참이면 참 값을 , 거짓이면 거짓값을 보여준다. */}
<div>{text}</div>
</div>
<div
onClick={() => {
onRemove(id);
}}
>
{/* const onRemove = useCallback((id) => {
setTodos(todos.filter((todo) => todo.id !== id));
},[todos]);
클릭을 하게 되면 id값이 인자로 들어가서 일치하게되어
해당 클릭값부분만 제외하고 다시 새 배열로 받아온다. */}
<MdRemoveCircleOutline />
</div>
</TodoListItemBox>
);
};
export default TodoListItem;
💬 저번에 이해하지 못했던 부분을 이해하려고 다시 기능 구현까지 해보았다.
10.06 - 팀원에게 속성 과외를 받아 어느 정도 이해가 되었다.
이 내용을 바탕으로 장바구니 부분의 값을 받아올 수 있게 되었다.