Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions .gitignore

This file was deleted.

70 changes: 0 additions & 70 deletions README.md

This file was deleted.

49 changes: 49 additions & 0 deletions cleancode/overview/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {useState,useEffect} from 'react';

const useFetch = async () =>{
// eslint-disable-next-line react-hooks/rules-of-hooks
const 연결전문가 = await 연결전문가_받아오기();
return 연결전문가

}

function QuestionPage(){
const 연결전문가 = useFetch(); // 처음 켰을때 실행

async function handleNewExpertQuestionSubmit(){
await 질문전송(questionValue);
alert("질문이 들어왔어요");
}

async function handleMyExpertQuestionSubmit(){
await 연결전문가_질문전송(questionValue, 연결전문가.id);
alert(`${연결전문가.name}에게 질문이 등록되었어요.`)
}

return (
<main>
<form>
<textarea palceholder="어떤 내용이 궁금한가요"/>
{연결전문가.connected ? (
<PopupTriggerButton popup={(<연결전문가팝업 onSubmit={handleMyExpertQuestionSubmit}></연결전문가팝업>)}>
질문하기
</PopupTriggerButton> // 팝업이 열릴지 handleQuestion을 봤어야했는데 이제는 이 줄에서 모든것을 확인가능하다
):
<button onClick={async()=>{
await openPopupToNotAgreedUser();
await handleNewExpertQuestionSubmit();
}}>

</button>
}
</form>
</main>
)
}

async function openPopupToNotAgreedUser(){
const 약관동의 = await 약관동의_받아오기();
if(!약관동의){
await 약관동의_팝업열기();
}
}
41 changes: 41 additions & 0 deletions cleancode/overview/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {useState,useEffect} from 'react';

function QuestionPage(){
const [popupOpend, setPopupOpend] = useState(false);
async function handleQuestionSubmit(){
const 연결전문가 = await 연결전문가_받아오기();
if(연결전문가 !== null){
setPopupOpend(true);
}else{
const 약관동의 = await 약관동의_받아오기();
if(!약관동의){
await 약관동의_팝업열기();
}
await 질문전송(questionValue);
alert("질문이 들어왔어요");
}
}
async function handleExpertQuestionSubmit(){
await 연결전문가_질문전송(questionValue, 연결전문가.id);
alert(`${연결전문가.name}에게 질문이 등록되었어요.`)
}

return (
<main>
<form>
<textarea palceholder="어떤 내용이 궁금한가요"/>
<button onClick={handleQuestionSubmit}>질문하기</button>
</form>
{popupOpend &&(
<연결전문가팝업 onSubmit={handleMyExpertQuestionSubmi}/>
)}
</main>
)
}

/*
문제점
1. 응집도 : 하나의 목적의 코드는 흩뿌려져서는 안된다 . popupOpened를 관리하는 함수 실제 열리는곳이 3군데로 흩뿌려져잇다
2. 단일책임 : 함수는 하나의 일을 해야한다.
3. 추상화 : 함수의 구현 레벨이 같아야한다.
*/
50 changes: 50 additions & 0 deletions cleancode/응집도/after1 notanswer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {useState,useEffect,useRef} from 'react';

const useFetch = async () =>{
// eslint-disable-next-line react-hooks/rules-of-hooks
const 연결전문가 = await 연결전문가_받아오기();
return 연결전문가
}

const useModal=()=>{
const [popupOpened,setPopupOpened] = useState(false);

const handlePopupSubmit = async()=>{
await 질문전송(연결전문가.id);
alert("질문을 전송했습니다")
}

const openPopup = ()=>{
$target.innerHTML += (<Popup title="보험 질문하기">
<div>전문가가 설명드려요</div>
<button onClick={handlePopupSubmit}></button>
</Popup>)
}
return openPopup;
}

function Question(){
const 연결전문가 = useFetch();
const openPopup = usePopup();
async function handleClick($target){
openPopup($target);
}

return (
<div ref={currentDiv}>
<button onClick={handleClick(currentDiv.current)}>질문하기</button>
</div>
)
}

/*문제점
1. 어떤내용의 팝업을 띄우는지 알 수없다.
2. 팝업에서 버튼을 눌렀을때 어떤 액션을하는지 알 수 없다.
가장 중요한것이 위의 2가지인데 커스텀훅 속에 가려진 안티패턴이다.
*/

/*
당장 몰라도 되는 디테일은 훅이나 컴포넌트속에 숨긴다.
코드파악에 필수적인 정보는 뭉치지 않는다.
뭉쳐서 코드가 짧아진다고 코드가 깨끗해지는 것이 아니다.
*/
39 changes: 39 additions & 0 deletions cleancode/응집도/after2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {useState,useEffect} from 'react';

const usePopup = ($target) =>{
const openPopup = (title,contents) =>{
$target.innerHTML += (<Popup title={title}>
<div>{contents}</div>
<button onClick={handlePopupSubmit}></button>
</Popup>)
}
return openPopup
}

function Question(){
const openPopup = usePopup();
async function handleClick(){
const confirmed = await openPopup({
title: "보험질문하기",
contents:<div>전문가가 설명드려요</div>
})
if(confirmed){
await submitQuestion();
}
}

async function submitQuestion(){
await 질문전송(연결전문가.id);
alert("질문을 전송했습니다")
}

return (
<div>
<button onClick={handleClick}>질문하기</button>
</div>
)
}

// 핵심내용은 popup제목, popup내용, popup액션이다.
// 세부내용은 popup을 열고 닫을때 사용하는 상태와 컴포넌트의 세부마크업, 팝업 버튼클릭시 특정함수를 호출해야한다는 바인딩
//
26 changes: 26 additions & 0 deletions cleancode/응집도/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {useState,useEffect} from 'react';

function Question(){
const [popupOpend,setPopupOpend] = useState(false); // ☆
async function handleClick(){
setPopupOpend(true);
}

async function handlePopupSubmit(){ // ☆
await 질문전송(연결전문가.id);
alert("질문을 전송했습니다")
}

return (
<div>
<button onClick={handleClick}>질문하기</button>
{popupOpend && <Popup title="보험 질문하기"> {/*☆*/}
<div>전문가가 설명드려요</div>
<button onClick={handlePopupSubmit}></button>
</Popup>}
</div>
)
}

//팝업을 조작하는 코드가 ☆ 의 3군대 뚝뚝 떨어져 있다.
//팝업 열기조작, 팝업 전송조작, 팝업 html
3 changes: 3 additions & 0 deletions cleancode/추상화/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Popup onSubmit={회원가입} onSuccess={프로필이동}></Popup>

//제출 액션과 성공 액션 코드만 남기고 추상화 하였다.
9 changes: 9 additions & 0 deletions cleancode/추상화/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div style={팝업스타일}>
<button onClick={async()=>{
const res = await 회원가입();
if(res.success){
프로필이동();
}

}}>전송</button>
</div>
5 changes: 5 additions & 0 deletions cleancode/컴포넌트단일책임1/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<LogClick message="제출버튼클릭">
<button onClick={openConfirm}/>
</LogClick>

//로그는 버튼을 감싼 컴포넌트에서 찍고 버튼클릭함수에서는 API콜만 신경쓴다.
6 changes: 6 additions & 0 deletions cleancode/컴포넌트단일책임1/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<button onClick={()=>{
log('제출버튼 클릭');
await openConfirm();
}}/>

//버튼 클릭 함수에 로그찍는 함수와 API 콜이 섞여있다.
11 changes: 11 additions & 0 deletions cleancode/컴포넌트단일책임2/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {useState,useEffect,useRef} from 'react';

function Test(){
return (
<IntersecionArea onImpression={()=>fetchCats(nextPage)}>
<div >더 보기</div>
</IntersecionArea>
)
}

//Impression 옵저버 세부 구현은 감싼 컴포넌트에 숨겨두고, 사용하는 입장에서는 Impression시 api콜만 신경쓴다.
21 changes: 21 additions & 0 deletions cleancode/컴포넌트단일책임2/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {useState,useEffect,useRef} from 'react';

function Test(){
const targetRef = useRef();
useEffect(()=>{
const observer = new IntersectionObserver(
([{isIntersecting}]) =>{
if(isIntersecting){
fetchCats(nextPage)
}
}
);
return () =>{
observer.unobserve(targetRef.current);
}
})

return <div ref={targetRef}>더 보기</div>
}

//intersection 부분과 api콜이 섞여있는것이 아쉽다.
13 changes: 13 additions & 0 deletions cleancode/함수단일책임/aflter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
async function handle약관동의(){
const 약관동의 = await 약관동의_받아오기();
if(!약관동의){
await 약관동의_팝업열기();
}
}

async function handle질문제출(){
await 질문전송(questionValue);
alert("질문이 등록되었어요")
}

//두개만 가지고 나중에 필요한 상황에 따로따로 호출하면된다.
Loading