의견이 있는 반응: 상태 관리
24216 단어 reactreduxjavascriptcodequality
소개
저는 4년 넘게 React와 함께 일해 왔습니다. 이 시간 동안 나는 응용 프로그램이 어떻게 되어야 한다고 생각하는지에 대한 몇 가지 의견을 형성했습니다. 이것은 그러한 독단적인 작품 시리즈의 3부입니다.
내가 다룰 내용
상태 관리에는 많은 부분이 있습니다. 한자리에 다 담을 수 없습니다. 이 게시물에서는 일반 React를 사용하여 구성 요소의 상태를 관리하는 방법을 보여 드리겠습니다.
다음에 대해 쓸 국가 관리와 관련된 향후 게시물을 보려면 저를 팔로우하세요.
상태 관리에는 많은 부분이 있습니다. 한자리에 다 담을 수 없습니다. 이 게시물에서는 일반 React를 사용하여 구성 요소의 상태를 관리하는 방법을 보여 드리겠습니다.
다음에 대해 쓸 국가 관리와 관련된 향후 게시물을 보려면 저를 팔로우하세요.
그냥 React를 사용하세요
나는 팀이 React의 내장 상태 관리 솔루션을 사용하기 전에 Redux, MobX 또는 다른 것과 같은 상태 관리 라이브러리를 채택하는 것을 너무 자주 보았습니다.
이 라이브러리에는 아무런 문제가 없지만 완전히 작동하는 React 애플리케이션을 빌드하는 데 필요한 것은 아닙니다. 내 경험상 일반 React를 사용하는 것이 훨씬 쉽습니다.
useState
또는 useReducer
를 사용하는 대신 이러한 라이브러리 중 하나를 사용해야 하는 이유가 있다면 귀하의 사용 사례를 알고 싶기 때문에 의견을 남겨주세요.
다음에 구성 요소를 빌드할 때 일반 React를 사용해 보세요.
후크
위에서 useState
및 useReducer
두 개의 후크를 언급했습니다. 다음은 각각을 사용하는 방법입니다.
useState로 시작
먼저 useState 후크로 구성 요소를 빌드합니다. 빠르고 작업을 완료합니다.
const MovieList: React.FC = () => {
const [movies, setMovies] = React.useState<Movie[]>([])
React.useEffect(() => {
MovieService
.fetchInitialMovies()
.then(initialMovies => setMovies(initialMovies))
}, [])
return (
<ul>
{movies.map(movie => <li key={movie.id}>{movie.title}</li>}
</ul>
)
}
다른 상태 조각이 필요한 경우 다른 useState
후크를 추가하기만 하면 됩니다.
const MovieList: React.FC = () => {
const [isLoading, setIsLoading] = React.useState<boolean>(true)
const [movies, setMovies] = React.useState<Movie[]>([])
React.useEffect(() => {
MovieService
.fetchInitialMovies()
.then(initialMovies => setMovies(initialMovies))
.then(() => setIsLoading(false))
}, [])
if (isLoading) {
return <div>Loading movies...</div>
}
return (
<ul>
{movies.map(movie => <li key={movie.id}>{movie.title}</li>}
</ul>
)
}
상태가 많을 때 useReducer
관련 상태 조각에 대한 내 제한은 2입니다. 서로 관련된 상태 조각이 3개 있으면 useReducer
를 선택합니다.
위의 예에 따라 영화 가져오기에 실패한 경우 오류 메시지를 표시하고 싶다고 가정해 보겠습니다.
다른 useState
호출을 추가할 수도 있지만 좀 지저분해 보이는 것 같아요 😢.
export const MovieList: React.FC = () => {
const [isLoading, setIsLoading] = React.useState<boolean>(true);
const [movies, setMovies] = React.useState<Movie[]>([]);
const [error, setError] = React.useState<string>("");
const handleFetchMovies = () => {
setIsLoading(true); // 😢
setError(""); // 😢
return MovieService.fetchInitialMovies()
.then(initialMovies => {
setMovies(initialMovies);
setIsLoading(false); // 😢
})
.catch(err => {
setError(err.message); // 😢
setIsLoading(false); // 😢
});
};
React.useEffect(() => {
handleFetchMovies();
}, []);
if (isLoading) {
return <div>Loading movies...</div>;
}
if (error !== "") {
return (
<div>
<p className="text-red">{error}</p>
<button onClick={handleFetchMovies}>Try again</button>
</div>
);
}
return (
<ul>
{movies.map(movie => (
<li key={movie.id}>{movie.title}</li>
))}
</ul>
);
};
useReducer
를 사용하도록 이것을 리팩토링하여 논리를 단순화합니다.
interface MovieListState {
isLoading: boolean;
movies: Movie[];
error: string;
}
type MoveListAction =
| { type: "fetching" }
| { type: "success"; payload: Movie[] }
| { type: "error"; error: Error };
const initialMovieListState: MovieListState = {
isLoading: true,
movies: [],
error: ""
};
const movieReducer = (state: MovieListState, action: MoveListAction) => {
switch (action.type) {
case "fetching": {
return { ...state, isLoading: true, error: "" };
}
case "success": {
return { ...state, isLoading: false, movies: action.payload };
}
case "error": {
return { ...state, isLoading: false, error: action.error.message };
}
default: {
return state;
}
}
};
export const MovieList: React.FC = () => {
const [{ isLoading, error, movies }, dispatch] = React.useReducer(
movieReducer,
initialMovieListState
);
const handleFetchMovies = () => {
dispatch({ type: "fetching" });
return MovieService.fetchInitialMovies()
.then(initialMovies => {
dispatch({ type: "success", payload: initialMovies });
})
.catch(error => {
dispatch({ type: "error", error });
});
};
React.useEffect(() => {
handleFetchMovies();
}, []);
if (isLoading) {
return <div>Loading movies...</div>;
}
if (error !== "") {
return (
<div>
<p className="text-red">{error}</p>
<button onClick={handleFetchMovies}>Try again</button>
</div>
);
}
return (
<ul>
{movies.map(movie => (
<li key={movie.id}>{movie.title}</li>
))}
</ul>
);
};
Q&A
모든 게시물은 트위터에서 받은 질문에 답할 것입니다. 이번주 질문입니다.
내 주요 문제는 내가 언제 Redux를 사용해야 하는지 이해하지 못한다는 것입니다. 나는 Redux를 싫어하지 않습니다. 그것이 어떻게 작동하는지 (간단한 방법으로) 알고 있지만 Redux, Effector 또는 MobX와 같은 상태 관리자와 비교하여 후크가 충분하지 않은 이유를 이해하지 못합니다. 이에 대한 의견을 듣고 싶습니다. v1rtl (@v1rtl )
나는 더 이상 redux를 사용하지 않습니다. React의 컨텍스트 API가 출시된 이후로 사용하지 않았습니다. IMO, 후크 + 컨텍스트가 애플리케이션을 빌드하기에 충분하다고 생각합니다.
마무리
이것은 내가 쓸 시리즈의 3번째 기사입니다. 재밌게 보셨다면 아래 댓글 부탁드립니다. 내가 뭘 더 덮고 싶니? 항상 그렇듯이 저는 피드백과 권장 사항에 열려 있습니다.
읽어 주셔서 감사합니다.
추신 아직 확인하지 않았다면 이 시리즈의 이전 게시물을 확인하십시오.
위에서
useState
및 useReducer
두 개의 후크를 언급했습니다. 다음은 각각을 사용하는 방법입니다.useState로 시작
먼저 useState 후크로 구성 요소를 빌드합니다. 빠르고 작업을 완료합니다.
const MovieList: React.FC = () => {
const [movies, setMovies] = React.useState<Movie[]>([])
React.useEffect(() => {
MovieService
.fetchInitialMovies()
.then(initialMovies => setMovies(initialMovies))
}, [])
return (
<ul>
{movies.map(movie => <li key={movie.id}>{movie.title}</li>}
</ul>
)
}
다른 상태 조각이 필요한 경우 다른
useState
후크를 추가하기만 하면 됩니다.const MovieList: React.FC = () => {
const [isLoading, setIsLoading] = React.useState<boolean>(true)
const [movies, setMovies] = React.useState<Movie[]>([])
React.useEffect(() => {
MovieService
.fetchInitialMovies()
.then(initialMovies => setMovies(initialMovies))
.then(() => setIsLoading(false))
}, [])
if (isLoading) {
return <div>Loading movies...</div>
}
return (
<ul>
{movies.map(movie => <li key={movie.id}>{movie.title}</li>}
</ul>
)
}
상태가 많을 때 useReducer
관련 상태 조각에 대한 내 제한은 2입니다. 서로 관련된 상태 조각이 3개 있으면
useReducer
를 선택합니다.위의 예에 따라 영화 가져오기에 실패한 경우 오류 메시지를 표시하고 싶다고 가정해 보겠습니다.
다른
useState
호출을 추가할 수도 있지만 좀 지저분해 보이는 것 같아요 😢.export const MovieList: React.FC = () => {
const [isLoading, setIsLoading] = React.useState<boolean>(true);
const [movies, setMovies] = React.useState<Movie[]>([]);
const [error, setError] = React.useState<string>("");
const handleFetchMovies = () => {
setIsLoading(true); // 😢
setError(""); // 😢
return MovieService.fetchInitialMovies()
.then(initialMovies => {
setMovies(initialMovies);
setIsLoading(false); // 😢
})
.catch(err => {
setError(err.message); // 😢
setIsLoading(false); // 😢
});
};
React.useEffect(() => {
handleFetchMovies();
}, []);
if (isLoading) {
return <div>Loading movies...</div>;
}
if (error !== "") {
return (
<div>
<p className="text-red">{error}</p>
<button onClick={handleFetchMovies}>Try again</button>
</div>
);
}
return (
<ul>
{movies.map(movie => (
<li key={movie.id}>{movie.title}</li>
))}
</ul>
);
};
useReducer
를 사용하도록 이것을 리팩토링하여 논리를 단순화합니다.interface MovieListState {
isLoading: boolean;
movies: Movie[];
error: string;
}
type MoveListAction =
| { type: "fetching" }
| { type: "success"; payload: Movie[] }
| { type: "error"; error: Error };
const initialMovieListState: MovieListState = {
isLoading: true,
movies: [],
error: ""
};
const movieReducer = (state: MovieListState, action: MoveListAction) => {
switch (action.type) {
case "fetching": {
return { ...state, isLoading: true, error: "" };
}
case "success": {
return { ...state, isLoading: false, movies: action.payload };
}
case "error": {
return { ...state, isLoading: false, error: action.error.message };
}
default: {
return state;
}
}
};
export const MovieList: React.FC = () => {
const [{ isLoading, error, movies }, dispatch] = React.useReducer(
movieReducer,
initialMovieListState
);
const handleFetchMovies = () => {
dispatch({ type: "fetching" });
return MovieService.fetchInitialMovies()
.then(initialMovies => {
dispatch({ type: "success", payload: initialMovies });
})
.catch(error => {
dispatch({ type: "error", error });
});
};
React.useEffect(() => {
handleFetchMovies();
}, []);
if (isLoading) {
return <div>Loading movies...</div>;
}
if (error !== "") {
return (
<div>
<p className="text-red">{error}</p>
<button onClick={handleFetchMovies}>Try again</button>
</div>
);
}
return (
<ul>
{movies.map(movie => (
<li key={movie.id}>{movie.title}</li>
))}
</ul>
);
};
Q&A
모든 게시물은 트위터에서 받은 질문에 답할 것입니다. 이번주 질문입니다.
내 주요 문제는 내가 언제 Redux를 사용해야 하는지 이해하지 못한다는 것입니다. 나는 Redux를 싫어하지 않습니다. 그것이 어떻게 작동하는지 (간단한 방법으로) 알고 있지만 Redux, Effector 또는 MobX와 같은 상태 관리자와 비교하여 후크가 충분하지 않은 이유를 이해하지 못합니다. 이에 대한 의견을 듣고 싶습니다. v1rtl (@v1rtl )
나는 더 이상 redux를 사용하지 않습니다. React의 컨텍스트 API가 출시된 이후로 사용하지 않았습니다. IMO, 후크 + 컨텍스트가 애플리케이션을 빌드하기에 충분하다고 생각합니다.
마무리
이것은 내가 쓸 시리즈의 3번째 기사입니다. 재밌게 보셨다면 아래 댓글 부탁드립니다. 내가 뭘 더 덮고 싶니? 항상 그렇듯이 저는 피드백과 권장 사항에 열려 있습니다.
읽어 주셔서 감사합니다.
추신 아직 확인하지 않았다면 이 시리즈의 이전 게시물을 확인하십시오.
이것은 내가 쓸 시리즈의 3번째 기사입니다. 재밌게 보셨다면 아래 댓글 부탁드립니다. 내가 뭘 더 덮고 싶니? 항상 그렇듯이 저는 피드백과 권장 사항에 열려 있습니다.
읽어 주셔서 감사합니다.
추신 아직 확인하지 않았다면 이 시리즈의 이전 게시물을 확인하십시오.
Reference
이 문제에 관하여(의견이 있는 반응: 상태 관리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/farazamiruddin/opinionated-react-state-management-426a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)