Redux는 도대체 무엇입니까?(2부)
그 중에서 나는 기본적인 React 구조를 소개했는데 우리가 깊이 들어가면서 점점 복잡해진다.마지막으로, 왜 우리가 우리 나라를 더욱 잘 조직할 수 있도록 도와야 하는지 잘 알고 있다.이 두 번째 부분의 글에서 저는 Redux가 어떻게 상태 관리를 간소화하고 Redux를 실제로 사용하는지 설명하고 지난주 명부의 예시를 Redux 흐름으로 훑어보겠습니다.
주의: 이것은 완전한 React/Redux 강좌가 아니라 관련 개념을 설명하는 고급 개술이다.
참고로 Redux가 무엇인지 요약했습니다.
Redux provides a Store object, accessible from anywhere in your React app, which contains the state of the entire application, as well as the data flow pattern for how to interact with it.
이 그림은 다시 이런 패턴을 그려냈다.
React 데이터 흐름(그림:Tanya Bachuk
저, 우리 본론을 이야기하기 시작합시다.
우리의 문제
지난주의 명부 예시를 생각해 보세요. 그 중에서 우리는 여러 개의 관련 구성 요소가 있습니다. 여러 용기에 포함되고, 모든 구성 요소는state에 포함된 데이터에 접근합니다.
예: 짙은 녹색 및 연한 녹색 영역은 독립적인 컨테이너 구성 요소입니다.
React without Redux에서 어떻게 설정했는지 생각해 보세요.우리는 두 개의 단독 용기 요소의 부모 요소인 두 번째 용기 구성 요소를 만들어야 한다.우리는 비록 이것은 매우 복잡하지만, 그것은 여전히 관리할 수 있지만, 더 큰 응용 프로그램에서는 곧 제어를 잃을 수 있다고 토론했다.
만약 우리가 어떤 방식으로 모든 구성 요소를 모든 데이터에 양방향으로 연결할 수 있다면, 매번 관련 구성 요소 간에 데이터를 전달해야 할 때마다 다른 새로운 층을 구축하는 것을 걱정하지 않는다면, 그것은 좋지 않겠는가?이것이 바로 Redux의 용도입니다.
가게를 세우다
우리가 해야 할 첫 번째 일은 사실상 하나의 용기 요소에서 모든 데이터를 얻고 그것들을 집중된 위치로 끌어들이는 것이다.이 집중된 위치는 상점이라고 불리며, 프로그램의 맨 위에 위치해 있으며, (통상적으로 index.js라고 부른다) 없는 곳이 없다.
감속기 생성
그래서 상점의 개념은 매우 직관적이지만, 우리는 실제로 그것을 어떻게 만듭니까?우리의 상점을 세우기 위해서 우리는 먼저 감속기라는 물건을 세워야 한다.reducer는 순수한 함수일 뿐입니다. 두 가지 목적이 있습니다. 첫째, 저장된 초기 상태 데이터를 설정하고, 둘째, 이 상태를 변경할 수 있습니다.상태가 실제로 직접적으로 변이된 것이 아니기 때문에 감축기는 호출할 때마다 새로운 상태로 되돌아온다.단순화 함수의 가장 간단한 형식은 다음과 같다.
function reducer(state, action) {code blocks};
감속기 상태 매개 변수
reducer의 "state"매개 변수는 함수 설명에서 프로그램의 초기 상태로 설정됩니다.이것은 우리의reducer 함수를 위에서 쓴 것보다 좀 복잡하게 보일 수 있지만, 그 문법은 똑같다는 것을 안심하십시오.상태는 여러 가지 유형의 데이터에 대한 정보를 포함할 수 있기 때문에 다음과 같이 객체 그룹을 포함하는 중첩 구조로 설정된 상태를 볼 수 있습니다.
function playersReducer(
state = { // start initial state declaration
players: [
{
id: **player's id**,
name: **player's name**,
score: 0 // initially the player will have no points
},
{
id: **player's id**,
name: **player's name**,
score: 0
}
]
}, action) { // end initial state declaration
// reducer code blocks
};
잠시 후에 우리는 이러한 조작에 대해 토론할 것이다. 그러나 이것은 상점을 만들고 우리의 전체 응용 프로그램에 게이머에 대한 정보를 제공하기에 충분하다.상점 만들기
일단 우리가 감속기를 잘 설치하면, 그것을 우리의 상점으로 바꾸는 것은 매우 간단하다.색인 구성 요소에서createStore () 함수를 사용하고reducer를 매개 변수로 전송하기만 하면 됩니다:
const store = createStore(playersReducer)
.지금 우리는 어느 곳에서든 방문할 수 있는 상점이 하나 생겼다.지금까지 Redux 그림에서 우리는 이 점을 해냈다.
상점 방문
중앙 상점이 아주 좋지만, 만약 우리가 그것을 방문할 수 없다면, 이것은 우리에게 그다지 좋은 점이 없다.
상점 연결
컨테이너의 React 구조를 계속 표시합니다. 모든 용기 구성 요소가 저장소에 포함된 데이터에 접근할 수 있기를 바랍니다.이를 위해서는 우선 Redux의connect() 함수를 사용하여 모든 구성 요소를 저장소에 연결해야 합니다.우리가 이렇게 하는 것은 부품 수출 성명의 일부분이다.
export default connect(args)(component);
.연결: MapStateTops
이 함수는 두 개의 매개 변수가 있습니다. 첫 번째 매개 변수는 "mapstatetops"입니다. 이것은 실제적으로 다른 Redux 함수입니다. 지정한 데이터를 저장소에서 구성 요소로 끌어다 도구로 접근할 수 있도록 합니다.
const mapStateToProps = state => {
return {
players: state.players
}
}
현재 유저 진열은 this.props.players
을 통해 구성 요소 내에 접근할 수 있습니다.우리도 어떤 구성 요소를 사용하든지 간에 이런 방식을 통해 비유저 데이터를 도입할 수 있다.가령 우리도 지금 코치에 대한 데이터를 수집해야 한다.const mapStateToProps = state => {
return {
players: state.players,
coaches: state.coaches
}
}
this.props.coaches
이것이 바로 Redux의 매력입니다.우리의 모든 데이터는 필요한 곳에서 접근할 수 있다.이것은 우리가 지금까지 얻은 성과를 보기 위해 아주 좋은 후퇴이다.우리의 데이터를 시각화하는 데 도움을 주기 위해서, 여기는 우리가 현재 익숙한 명부 응용 프로그램의 작업 흐름이지만, 이번에는 Redux global store를 사용합니다.저장이 이전처럼 단독 단계에 존재하지 않고 다른 용기 구성 요소를 둘러싼 방법에 주의하십시오.Redux가 있는 단방향 흐름
이것은 우리로 하여금 도표에서 더욱 진일보하게 한다.
스토리지 업데이트
지금 우리는 지난주에 토론한 같은 단방향 흐름 문제에 부딪혔다.Redux는 어떻게 상점의 정보를 업데이트하는 데 도움을 줍니까?
감속기 유량 설정
상태의 모든 변화는 우리의 감속기를 통과할 것이다.
감속기 동작 매개 변수
돌이켜 보면, 우리의 감속기는 두 개의 매개 변수가 있는데, 우리는 단지 첫 번째 것만 토론했습니까?여기는 두 번째 매개 변수,reducer(state,action)가 나타나는 곳입니다.reducer는 상태에 대한 업데이트가 필요한 명령을 포함하고 switch 문장을 사용하여 업데이트가 필요한 상태를 되돌려주는 액션 매개 변수를 받아들일 것입니다.
switch (action.type) {
case "ADD_PLAYER":
newPlayer = {**player_details**};
return [...state, newPlayer];
case "CHANGE_SCORE":
let playerIndex = state.findIndex(player => player.id === action.id); // index in state of the player
let changedPlayer = state[playerIndex]
changedPlayer.score = action.score // change the score
const newState = [...state] // copy current state
newState.splice(playerIndex, 1, changedPlayer) // replace current player score with new player score
return newState; // return the new, updated state
default:
return state;
};
작업 작성
동작은 감속기가 상태에 대해 무엇을 하는지 알려주는 것이다.동작은 하나의 대상일 뿐입니다. "type"항목과 (선택 사항) Reducer에 전달할 값을 포함합니다.그것들은 보통 actioncreator라고 불리는 순수한 함수를 통해 만들어집니다. 프로그램에서 이벤트가 발생하면 이 함수가 호출됩니다. (또는 스케줄링)다음과 같이 보입니다.
export const changeScore = player, score => { // action creator function
return { // return the action
type: 'CHANGE_SCORE',
id: player.id,
score: score
}
}
어셈블리에 작업 연결
마지막 난제는 우리가 상태를 바꾸기를 원하는 용기 구성 요소와 관련된 스케줄링 흐름을 어떻게 얻는가이다.
연결: mapDispatchToProps
이것은 Redux connect () 함수
connect(mapStateToProps, *mapDispatchToProps*)
의 두 번째 인자를 통해 완성된 것입니다.맵StateToProps와 유사하게, 맵DispatchToProps는 동작 생성자를 도구에 분배하여 우리 구성 요소에서 사용할 수 있도록 합니다.const mapDispatchToProps = dispatch => {
return {
changeScore: (player, score) => dispatch(changeScore(player, score)),
addPlayer: (player) => dispatch(addPlayer(player))
}
}
현재 우리는 입력 this.props.changeScore(selected_player, new_score)
을 통해 구성 요소에서 changeScore 작업을 호출할 수 있습니다.일단 우리가 이렇게 하면 데이터는 동작을 통해 우리의 구성 요소에서 우리의reducer로 흐르고, 그리고reducer는 데이터로 저장된 상태를 업데이트하여 우리의 도표를 완성할 것이다.이제 전체 Redux 흐름의 시각화를 살펴보겠습니다.
Redux를 사용한 전체 반응 데이터 흐름
이 작은 예시에서 즉각적으로 좋은 점을 보지 못할 수도 있습니다. 특히 Redux 구현에 관한 모든 작업을 읽은 후에 Coach 구성 요소를 추가하고 싶습니다.Redux를 사용하고 사용하지 않을 때의 효과 비교:
Redux 사용
Redux 없음
이것은 상당히 큰 개선이다. 물론 이것은 여전히 매우 간단한 예이다.우리가 점점 더 많은 구성 요소를 추가함에 따라 오른쪽의 흐름은 계속 복잡해지고 왼쪽의 Redux 흐름은 같은 외관과 매끄러운 축소를 유지할 것이다.
최종 워크플로우
우리 한번 되돌아봅시다.Redux를 구현하기 위해 다음 단계를 수행했습니다.
본고의 목적은 Redux의 개념을 보여주는 것이지 응용 프로그램을 구축하는 강좌가 아니기 때문에 아래의 코드는 완전한 응용 프로그램이 아니라는 것을 기억하십시오
이 부분의 조합 코드는 다음과 유사하다.
// Index.js
const store = createStore(rootReducer, applyMiddleware(thunk));
ReactDOM.render(
// **React index code**
);
// Reducer
function playersReducer(
state = { // start initial state declaration
players: [
{
id: 1,
name: "John",
score: 0 // initially the player will have no points
},
{
id: 2,
name: "Bob",
score: 0
}
]
}, action) { // end initial state declaration
switch (action.type) {
case "ADD_PLAYER":
newPlayer = {id: action.id, name: action.name, score: 0};
return [...state, newPlayer];
case "CHANGE_SCORE":
let playerIndex = state.findIndex(player => player.id === action.id); // index in state of the player
let changedPlayer = state[playerIndex]
changedPlayer.score = action.score // change the score
const newState = [...state] // copy current state
newState.splice(playerIndex, 1, changedPlayer) // replace current player score with new player score
return newState; // return the new, updated state
default:
return state;
};
};
// Action Creator
export const changeScore = player, score => { // action creator function
return { // return the action
type: 'CHANGE_SCORE',
id: player.id,
score: score
}
};
// ContainerComponents
class PlayersContainer extends Component {
// Insert Component Code Here
};
const mapStateToProps = state => {
return {
players: state.players
}
};
const mapDispatchToProps = dispatch => {
return {
changeScore: (player, score) => dispatch(changeScore(player, score)),
addPlayer: (player) => dispatch(addPlayer(player))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(playersContainer);
마지막으로, 이 프레임워크를 사용하는 더 복잡한 예시가 어떤 모습인지 알고 싶다면, 제가 React/Reduxhere로 구축한 쇼핑몰 코드를 마음대로 보십시오.React와 Redux 사용에 대해 어떻게 생각하십니까?너는 그들의 무엇을 좋아하거나 좋아하지 않니?댓글로 알려주세요!
Reference
이 문제에 관하여(Redux는 도대체 무엇입니까?(2부)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dhintz89/what-is-redux-anyway-part-2-1gf4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)