리액트를 정리하고자 유튜브에 Codevolution 채널(https://www.youtube.com/channel/UC80PWRj_ZU8Zu0HSMNVwKWw)에서 ReactJS Toturial을 학습했다.
이번 포스팅은 아는 내용들은 빠르게 넘어갔고, 중요하다 싶은 내용이나 가물가물하던 내용들을 내가 이해한 바를 기록하는 용도이다. 따라서, 설명,예제 등 생략된 부분이 많다.
파라미터로 props를 넘기면 해당 컴포넌트의 attribute가 Object형태로 넘어간다.
// App.js
<Hello name="Bruce" heroName="Batman" />
// Hello.js
const Hello = (props) => {
console.log(props);
return (
<>
<p>
// 프로퍼티의 값을 가져올 수 있음.
Hello, {props.name} aka {props.heroName}
</p>
</>
);
};
// console.log
{name: "Bruce", heroName: "Batman"}
동적인 데이터를 다룰 때 쓴다. setState()
를 통해 비동기적으로 함수를 호출하는데 이것이 호출되면 render()
가 호출됨. => view가 계속 업데이트된다는 것.
const Counter = ({count}) => {
return (
<>
<p>{count}</p>
</>
);
};
<> </>
주로 사용한다)// 버튼을 클릭하지도 않았는데 이미 실행되어버린다. 이후에 버튼을 클릭 해도 실행 안된다.
<button onClick={clickHandler()}>Click</button> X
<button onClick={clickHandler}>Click</button> O
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
import React, { useState } from "react";
const Whoru = () => {
const [name, setName] = useState({ firstName: "", lastName: "" });
return (
<>
<input
type="text"
value={name.firstName}
//setName할때, 업데이트 외에 부분은 ...연산자로 초기화 되지 않게 한다.
onChange={(e) => setName({ ...name, firstName: e.target.value })}
/>
<input
type="text"
value={name.lastName}
onChange={(e) => setName({ ...name, lastName: e.target.value })}
/>
<h2> Your firstName is : {name.firstName}</h2>
<h2> Your lastName is : {name.lastName}</h2>
</>
);
};
export default Whoru;
A component is changing an uncontrolled input of type text to be controlled error in ReactJS : https://stackoverflow.com/questions/47012169/a-component-is-changing-an-uncontrolled-input-of-type-text-to-be-controlled-erro
useEffect(() => {
effect
return () => {
cleanup
}
}, [input])
여러개의 컴포넌트를 거쳐서 props, state 를 전달할 때 유용하다.
provider가 store라 생각하자.
시각적으로 잘 보여준다.
(https://xiubindev.tistory.com/105)
코드적으로 흐름을 살피기에 좋다.
(https://sg-choi.tistory.com/240)
// context 생성
import React , {createContext, useContext} from 'react';
export const NameContext = createContext();
// Provider 컴포넌트로 랜더링 할 컴포넌트를 감싸준다.
// 넘겨줄 값을 value에 넣는다.
<NameContext.Provider value="ape">
<Human />
</NameContext.Provider>
// 전달 하고자 하는 컴포넌트에서 useContext로 조회한다.
const Name = useContext(NameContext)
return (
<div>
<p>Hello, {name}</p>
</div>
)
const initialState = {
firstCounter: 0,
secondCounter : 10
};
const reducer = (state, action) => {
switch(action.type) {
case 'increment' :
return { ...state, firstCounter : state.firstCounter + action.value}
case 'decrement' :
return { ...state, firstCounter : state.firstCounter - action.value}
case 'increment2' :
return { ...state, secondCounter : state.secondCounter + action.value}
case 'decrement2' :
return { ...state, secondCounter : state.secondCounter - action.value}
case 'reset' :
return initialState
default:
return state
}
}
function Counter() {
const [count, dispatch] = useReducer(reducer, initialState)
return (
<div>
<div>1st Count : {count.firstCouner}</div>
<div>2nd Count : {count.secondCounter}</div>
<button onClick={() => dispatch({type:'increment', value : 1})}>Increment 1</button>
<button onClick={() => dispatch({type:'decrement', value : 1})}>Decrement 1</button>
<button onClick={() => dispatch({type:'increment', value : 5})}>Increment 5</button>
<button onClick={() => dispatch({type:'decrement', value : 5})}>Decrement 5</button>
<button onClick={() => dispatch({type:'reset'})}>Reset</button>
<button onClick={() => dispatch({type:'increment2', value : 1})}>Increment 1</button>
<button onClick={() => dispatch({type:'decrement2', value : 1})}>Decrement 1</button>
</div>
)
}
useCallback
과useMemo
를 제대로 사용 하는 법 :
(https://atercatus.github.io/react/2020-01-07-useMemo-useCallback)
useMemo
는 큰 데이터 처리에 사용해야하며,useCallback
은 쓸모없는 렌더링을 피하기 위해 코드에 더 많은 종속성을 추가하는 방법이다.
(https://blog.hackages.io/react-hooks-usecallback-and-usememo-8d5bb2b67231)
연관있는 컴포넌트가 값이 바뀔 때 전부 리랜더가 된다. -> 퍼포먼스 이슈가 생긴다.
Component를 React.memo
로 감싸주면 컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링을 하도록해 준다.
export default React.memo(component);
React에서 컴포넌트가 다시 렌더링 될 때에는 컴포넌트 안에 선언된 함수들을 새로 생성한다.
그래서 계속 렌더링 되면 함수도 계속해서 새로 생성된다는 것.
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
메모이제이션된 콜백을 반환합니다.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
메모이제이션된 값을 반환합니다.
특정 Dom을 선택해야 하는 상황에 사용.
import React, { useEffect, useRef } from "react";
function Focus() {
const inputRef = useRef(null);
useEffect(() => {
// focus the input el
inputRef.current.focus();
}, []);
return (
<div>
<input ref={inputRef} type="text" />
</div>
);
}
export default Focus;
hooks로 useContext와 useReducer를 공부하면서 어려웠던 Redux가 어느정도 가닥이 잡힌다. 😛😛
다시금 느끼는 거지만 역시 공식 레퍼런스 만한게 없다.
(https://ko.reactjs.org/docs/hooks-reference.html)