redux의 장점: 원리가 간단해서 에러가 잘 생기지 않고 에러가 발생해도 추적하기 쉽다. 따라서 앱이 안정적이 된다.
redux의 단점: 코드량이 많다 -> next-redux-wrapper를 쓰면 편하다
mobx의 장점: 코드량이 적고 생산성이 높아진다
mobx의 단점: 에러 발생시 추적(트래킹)이 어렵다
컨텍스트 API는 비동기를 지원하기 쉽지 않다는 단점, 요청 성공 실패 3가지를 다 직접 구현해줘야 한다.
예를 들면 아래와 같은 코드가 컴포넌트에 많이 들어가게 된다.
axios.get('/data')
.then(()=>{setData()})
.catch(()=>{serError(error)})
화면을 비즈니스 로직(데이터 요청)과 분리하는게 컴포넌트의 역할(화면을 그리는 것)에 더 적절하다? -> 컨텍스트 API로 구현하다보면 결국엔 redux나 mobx처럼 구현을 하게 된다 -> 처음부터 전역상태관리 라이브러리를 사용하자!
앱이 커지면 중앙 저장소도 커지므로 redux에서 reducer를 여러개로 쪼개면 중앙 저장소가 커지는 것을 어느정도 방지할 수 있다
액션에 바꾸고 싶은 데이터를 담는다
dispatch로 저장소에 보낸다
reducer로 액션에 따른 데이터 변동사항을 저장소(state)에 반영한다 -> 액션을 하나 만들때마다 리듀서도 하나씩 만들어야 한다(state+reducer = store)
//action
{
type: 'CHANG_NICKNAME',
data: 'boogiecho'
}
//reducer
switch (action.type) //type은 액션객체의 이름
case 'CHANGE_NICKNAME':
return {
...state,
name: action.data
}
case 'CHANG_AGE':
return {
...state,
age: action.data
}
return {...state, age: action.data}
이렇게 하는 이유는 불변성때문? -> 새로운 객체를 만들어줘야(return) 데이터 변동이 추적 가능하기 때문이다. 개발모드는 데이터를 계속 보유하고 있지만 프로덕션모드(?)는 데이터를 버린다?(이해X)
객체안에 있는 데이터를 전부 새롭게 만들어 주지 않는 이유(...state)는 참조관계를 유지해야 하는 것들은 유지하도록 놔두는게 메모리를 많이 잡아먹지 않기 때문이다(비구조화 할당)
자바스크립트에서 불변성이란? 참조자료형의 경우 객체를 할당하면 두개의 변수가 같은 객체를 가리키므로 비교했을때 항상 true가 나오는 것
{} === {} : false
const a = {}
b = a
a === b : true
import { createWrapper } from "next-redux-wrapper";
const configureStore = () => {};
const wrapper = createWrapper(configureStore, {
debug: process.env.NODE_ENV === "development",
});
export default wrapper;
//2번째 전달인자는 옵션객체인데 옵션객체가 true면 redux에 관해서 좀 더 자세한 설명이 나온다 -> 코딩할 때 편하므로 꼭 넣어주세요
export default wrapper.withRedux(NodeBird);
const [text, setText] = useState("");
로 수정export const Global = createGlobalStyle `
.ant-card-cover {
transform: none !important;
}
const imageInput = useRef();
const onCLickImageUpload = useCallback(() => {
imageInput.current.click();
}, [imageInput.current]);
<div>
<input type="file" multiple hidden ref={imageInput} />
<Button onClick={onCLickImageUpload}>이미지 업로드</Button>
<Button
type="primary"
style={{ float: "right" }}
htmlType="submit"
>
짹짹
</Button>
</div>
<Card
cover={post.Images[0] && <PostImages images={post.Images} />}
actions={[
<RetweetOutlined key="retweet" />,
<HeartOutlined key="heart" />,
<MessageOutlined key="comment" />,
<Popover
key="more"
content={
<Button.Group>
{me.id && post.User.id === me.id ? (
<>
<Button>수정</Button>
<Button type="danger">삭제</Button>
</>
) : (
<Button>신고</Button>
)}
</Button.Group>
}
>
<EllipsisOutlined key="ellipsis" />
</Popover>,
]}
>
const me && me.id
-> const id = me?.id
me.id가 있으면 바꿔주고 없으면 undefined로 바꿔주는 연산자, id값이 있나없나를 체크후 있을때 값을 넣어준다<img role="presentation" onClick={onZoom}/>
는 스크린 리더가 onClick안에 있는 내용은 굳이 클릭할 필요가 없다는 의미를 담고있다. button이나 input이 아닌 애들은 role="presentation"을 넣어주자.최종
const PostCardContent = ({ postData }) => {
//split은 특이하게 정규표현식 내부를 소괄호로 감싸야한다
return (
<div>
{postData.split(/(#[^\s#]+)/g)}
</div>
);
};