재사용 가능한 함수_React

miin·2021년 10월 26일
0

React

목록 보기
25/55
post-thumbnail

DRY(Don`t Repeat Yourself)

  • 중복되는 로직을 추출해 반복적으로 사용하게되면 프로젝트의 코드량을 줄일 수 있다
  • 로직의 관리 포인트가 줄어들면서 개발자가 코드를 보다 쉽게 수정,추가 할 수 있게 된다
    ex)
// src/config.js
export const API = "http://localhost:8000";
// App.js
fetch(`${API}/product/1`);

KISS(Keep It Simple, Stupid)

  • 원칙은 복잡도를 낮추기 위해서 만든 것
  • 함수는 가급적 단순하게 유지되어야 한다
  • 줄여쓰겠다고 가독성을 과하게 희생시키지는 않았는지 살펴봐야한다
// DON'T
const fourRuleCalculate = (event, a, b) => {
	const { innerText } = event.target;
	
	if (innerText === "+") {
		return a + b
	} else if (innerText === "-") {
		return a - b
	} else if (innerText === "*") {
		return a * b
	} else if (innerText === "/") {
		return a / b
	}
}

// DO
const sum = (a, b) => a + b
const minus = (a, b) => a - b
const multiply = (a, b) => a * b
const divide = (a, b) => a / b

재사용 가능한 함수 만들어보기

  1. 변수화 할 수 있는 부분을 나누어 볼 수 있다
console.log("안녕하세요, " + "위코더" + "!");
  • 고정된 부분과 변경될 수 있는 부분을 나누어 생각해 볼 수 있다
  • 변경되는 부분에 대해서만 사용자의 입력을 받고, 나머지 부분은 반복적으로 출력하도록 할 수 있다.
  1. 변수화 할 수 있는 부분을 함수의 인자로 받아 사용
function sayHello(person) {
	console.log("안녕하세요, " + person + "!");
}

sayHello("위코더");
  1. 인자의 갯수를 늘려본다
function saySomething(message, person) {
	console.log(message + ", " + person + "!");
}

saySomething("안녕하세요", "위코더");
saySomething("안녕히가세요", "위코더");
  1. 인자가 다양한 타입에 대응하도록 한다
function saySomething(message, people) {
	const peopleArr = Array.isArray(people) ? people : [people]
	
	for (const person of peopleArr) {
		console.log(message + ", " + person + "!");
	}
}

saySomething("안녕하세요", "위코더1")
saySomething("안녕하세요", ["위코더1", "위코더2", "위코더3"]) 
  • 별도의 함수를 추가하지 않더라도 하나의 함수만으로 다양한 타입에 대응할 수있다
  • 과하게 많은 경우의수를 대비하지 않는다. 필요에 맞게 함수를 확장해주는게 좋다
  1. 객체 계산된 속성명
const foo = "속성"
const data = {
	["계산된" + foo + "명"]: "객체 계산된 속성명 문법!"
}

console.log(data["계산된속성명"])
// "객체 계산된 속성명 문법!"
  1. 함수 기본 매개변수
const sayHello = (message = "안녕하세요!") => {
	return message
}

sayHello() // "안녕하세요!"
sayHello("안녕히 가세요!") // "안녕히 가세요!"

프로젝트 실전 예제

handleInput 함수 공통 로직 합치기

handleId = (e) => {
  this.setState({ id: e.target.value });
};

handleName = (e) => {
  this.setState({ name: e.target.value });
};

handleEmail = (e) => {
  this.setState({ email: e.target.value });
};

handleAddress = (e) => {
  this.setState({ address: e.target.value });
};

=>

const handleInput = (e) => {
  const { name, value } = e.target;

	**// 객체 계산된 속성명**
  this.setState({ [name]: value });
};

localstorage로 access token 다루기

fetch("http://localhost:8000", {
	Authorization: localstorage.getItem("access_token")
})

fetch("http://localhost:8000")
	.then(res => res.json())
	.then(res => localStorage.setItem("access_token", res.token))

=>

  • 실습 코드
    const ACCESS_TOKEN_KEY = "access_token";
    
    export const getToken = () => {
    	const token = localstorage.getItem(ACCESS_TOKEN_KEY);
    
    	if (token) {
    		return token;
    	} else {
    		alert("토큰이 존재하지 않습니다!");
    		return "";
    	}
    }
    
    export const setToken = token => {
      localstorage.setItem(ACCESS_TOKEN_KEY, token)
    }
    export const tokenUtils = {
      get: getToken,
      set: setToken
    }
    
    fetch("http://localhost:8000", {
    	Authorization: tokenUtils.get()
    })
    
    fetch("http://localhost:8000")
    	.then(res => res.json())
    	.then(res => tokenUtils.set(res.token))

로그인/회원가입 유효성 검사 로직

const Form = () => {
	const [id, setId] = useState("");
	const [email, setEmail] = useState("");
	const [password, setPassword] = useState("");
	const [isAllValid, setIsAllValid] = useState(false);

	const handleId = (e) => {
		setId(e.target.value);
	}

	const handleEmail = (e) => {
		setEmail(e.target.value);
	}

	const handlePassword = (e) => {
		setPassword(e.target.value);
	}

	useEffect(() => {
		if (id.length > 6 && email.includes("@") && password.length > 8) {
			setIsAllValid(true);
		} else {
			setIsAllValid(false);
		}
	}, [id, email, password]);

	return (
		<div>
			<input type="text" name="id" onChange={handleId} />
			<input type="email" name="email" onChange={handleEmail} />
			<input type="password" name="password" onChange={handlePassword} />
			<button disabled={!isAllChecked} />
		</div>
	)
}

=>

  • state로 만들면 안되는 값이 state로 다뤄지고 있음(isAllValid)
  • 컴포넌트 안의 다른 state나 props를 가지고 계산 가능하다면 state가 아니다
  • 동일한 로직이 별도의 함수로 나뉘어 있음 (handleId, handleEmail, handlePassword)
  • 유효성 검사 로직이 특정 함수 안에 종속되어 있음 (id.length > 6 && email.includes("@") && password.length > 8)
// Form.js
const Form = () => {
	const [formValues, setFormValues] = useState({
		id: "",
		email: "",
		password: ""
	});

	const handleForm = e => {
		const { name, value } = e.target;

		**// 스프레드 연산자, 계산된 속성명**
		setFormValues({ ...formValues, [name]: value });
	}

	return (
		<div>
			<input type="text" name="id" onChange={handleForm} />
			<input type="email" name="email" onChange={handleForm} />
			<input type="password" name="password" onChange={handleForm} />
			<button disabled={!isAllValid(formValues)} />
		</div>
	)
}

// validator.js
export const validator = {
  //각각의 유효성 검사 함수
	id: id => id.length > 6,
	email: email => email.includes("@"),
	password: password => password.length > 10
}


// ver.1
export const isAllValid = form =>
	Object.entries(form).every(([key, value]) => validator[key](value))

// ver.2
export const isAllValid = form => {
	for (const name in form) {
		const value = form[name];
		const validateFunction = validator[name]

		if (!validateFunction(value)) return false;
	}
	
	return true;
}
//formValues가 모두 유효한지 검사하는 함수
//순회 돌면서 각각에 맞는 유효성 검사 함수 호출
//모든 유효성 검사가 true->isAllValid=>true 이중에 하나라도 false면 false
//const formValues = {
	id: '',
    email:'',
    password: '',
};
const isAllValid = (formValues) => {
  for(const key in formValues) {
    constole.log('key',key);
    ......
  }
}

0개의 댓글