useReducer를 사용하여 React 상태 관리 방법
30996 단어 reactwebdevjavascriptusereducer
질문
만약 네가 아직 나의 setting up redux in react,에 관한 문장을 읽지 않았다면, 나는 네가 본문에서 토론할 내용을 이해하기 위해 읽어 보라고 건의한다.
레드ux에 대한 주요 불평 중 하나는 상당히 간단한 기능을 설정하기 위해 대량의 샘플 코드가 필요하다는 것이다.redux와react redux를 포함해야 프로젝트의 묶음 규모를 증가시킬 수 있습니다.설정은 코드의 복잡성을 증가시켰다.
이것은 레드ux 개발자의 잘못이 아니다.Redux는 유일한 반응 도구가 아닌 일반적인 상태 관리 도구로 설계되었다.따라서 특정한 프레임에 적응하려면 그 프레임을 전문적으로 디자인한 것보다 많은 설정이 필요하다.
일부 초보자들에게 레드ux의 학습 곡선도 상당히 가파르다. 왜냐하면 그것은 파악하기 어려운 범례를 도입했기 때문이다.나는 적어도 2주일의 시간을 들여서 레드ux를 수리한 후에야 그것에 만족한다고 부끄럽지 않게 말했다.
redux의 복잡성은 대형 프로젝트에 있어서 합리적이다.주가 충분하고 복잡해지면서 정성스럽게 디자인된 레드ux 설정은 결국 이런 장면에서 자신을 위해 계산한다.
그러나 일부 프로젝트의 규모는 레드ux를 사용하는 것이 합리적이라는 것을 증명하기에는 부족하지만 포함된 상태가 너무 복잡해서 더 간단한useState 갈고리로 관리할 수 없다.이것이 바로 use Reducer의 용무의 땅입니다.
use Reducer가 이 문제를 어떻게 해결했는지
react 갈고리는 Redux에 추가된 상태 관리의 기본 기능을 제공합니다. 설정된 모든 샘플 코드가 필요하지 않습니다.
더 복잡한 상태 관리 시스템이 필요하지만, 레드ux에 추가된 기능이 필요하지 않은 항목은 (거의) 완벽한 선택이다.
use Reducer는react를 위한 디자인이기 때문에react 구성 요소에 집적하기 쉽습니다.
useReducer 갈고리는 더 많은 문제를 해결했습니다.나는 본문 뒤의 장점 부분에서 이 문제들을 토론할 것이다.
useReducer 사용
됐어, 그만해, 인코딩해야 돼!다음은 use Reducer의 실제 프레젠테이션입니다.이 강좌를 간소화하기 위해서, 나는 응용 프로그램 구성 요소에서 모든 코드를 짰다.
네가 적합하다고 생각하기만 하면 코드를 단독 구성 요소로 분해할 수 있다.어쨌든 이것은 모두 효과가 있을 것이다.
react에서 클래스 구성 요소에서 갈고리를 사용할 수 없기 때문에 기능 구성 요소를 사용할 것입니다.useReducer 훅을 가져오는지 확인합니다.
import React, { useReducer } from 'react';
이제 갈고리를 이용해보자.const reducer = (state, action) => {
switch (action.type) {
case 'ADD_LANGUAGE':
return { ...state, languages: [...state.languages, action.payload] }
case 'ADD_FRAMEWORK':
return { ...state, frameworks: [...state.frameworks, action.payload] }
case 'REMOVE_LANGUAGE':
return { ...state, languages: state.languages.filter( (language, index) => index !== action.payload ) }
case 'REMOVE_FRAMEWORK':
return { ...state, frameworks: state.frameworks.filter( (framework, index) => index !== action.payload ) }
default:
return state
}
}
const initialState = {
name: 'Kelvin Mwinuka',
occupation: 'Software Developer',
languages: ['JavaScript', 'Python'],
frameworks: ['React', 'Flask', 'Express']
}
const [state, dispatch] = useReducer(reducer, initialState)
만약 이전에 Redux를 사용한 적이 있다면, 많은 상황들이 익숙해 보일 것입니다.사실,use Reducer 갈고리는 기본적으로 Redux lite입니다.우선, 우리는 감속기를 설치한다.이것은 현재 상태와 스케줄링된 동작을 매개 변수로 합니다.동작 유형에 따라 현재 상태로 돌아가 관련 데이터(유효 부하)를 추가합니다.
다음은 초기 상태를 설정합니다.이것은 아마 빈 대상일 것이다.나는 첫 번째 렌더링을 할 때 뭔가를 보여주고 싶어서 여기에 일부 데이터를 초기 상태에 두었다.만약 당신이 이런 행위를 필요로 하지 않는다면, 마음대로 그것을 비워 두세요.
마지막으로, 우리는useReducer 갈고리를 사용하여 상태를 초기화하고 분배합니다.두 가지 주요 매개 변수는 감속기와 초기 상태다.
렌더링할 때 정보를 표시할 때 접근 상태를 표시하지만 디스패치를 사용하여 상태를 업데이트합니다.
이제 상태와 상호 작용할 수 있는 시각적 요소를 살펴보겠습니다.
return (
<div className="App">
<div>
<p><b>{state.name} </b>({state.occupation})</p>
<h3>Languages</h3>
<ul>
{state.languages.map((language, index) => {
return (
<li key={index}>
<b>{language}</b>
<button onClick={() => { dispatch({type: 'REMOVE_LANGUAGE', payload: index})} }>
Remove
</button>
</li>
)
})}
</ul>
<form onSubmit={handleSubmit}>
<input type='text' name='language' />
<input type='submit' value='Add Language' />
</form>
<h3>Frameworks</h3>
<ul>
{state.frameworks.map((framework, index) => {
return (
<li key={index}>
<b>{framework}</b>
<button onClick={() => { dispatch({type: 'REMOVE_FRAMEWORK', payload: index})} }>
Remove
</button>
</li>
)
})}
</ul>
<form onSubmit={handleSubmit}>
<input type='text' name='framework' />
<input type='submit' value='Add Framework' />
</form>
</div>
</div>
)
여기에서 우리는 두 개의 목록을 만들어서 각각 언어와 프레임워크를 보여 줍니다.모든 목록에는 상응하는 폼이 있는데, 우리가 그 안에 추가할 수 있도록 허락한다.또한 모든 목록 항목에 삭제 단추가 있습니다. 이 단추를 사용하면 목록에서 특정한 항목을 삭제할 수 있습니다.가장 간단한 논리가 있기 때문에 삭제 단추부터 시작합시다.나타나는 모든 삭제 단추는 목록에 있는 색인을 알고 있습니다.이 단추를 누르면 형식과 유효 부하가 있는 동작을 보냅니다. (redux와 같습니다.)
유효 하중은 버튼/항목의 인덱스입니다.그렇다면 감속기는 어느 목록에서 삭제해야 하는지 어떻게 알 수 있을까?
언어 목록에서 삭제 버튼을 클릭하면 REMOVE LANGUAGE 유형의 작업이 전송됩니다.보시다시피, Reducer는 이 특정 동작을 탐지하고, 언어 목록에서 부하에 있는 주어진 인덱스를 삭제합니다.
프레임 목록의 삭제 단추는 유사한 동작을 보냅니다. 단지 '프레임 삭제' 형식을 전달할 뿐입니다.reducer는 이런 종류의 동작을 감청하고 부하에서 전달된 색인에 있는 항목을 필터해서 응답합니다.
이제 목록에 추가된 문제를 처리합시다.
두 표 모두 같은 제출 처리 프로그램을 가지고 있다.응용 프로그램 구성 요소에서 이 점을 정의합니다.
const handleSubmit = (event) => {
event.preventDefault()
const formData = new FormData(event.target)
const language = formData.get('language') // Returns null if 'language' is not defined
const framework = formData.get('framework') // Returns null if 'framework' is not defined
const action = language ? {type: 'ADD_LANGUAGE', payload: language} :
framework ? {type: 'ADD_FRAMEWORK', payload: framework} : null
dispatch(action)
event.target.reset()
}
여기에서 우리는 표 제출 사건을 포착했다.그런 다음 양식에서 FormData 객체를 작성합니다.그런 다음 FormData에서 언어 및 프레임 값을 가져옵니다.프레임 폼에 대해 언어 키는null로 되돌아오고, 반대로도 마찬가지입니다.
그리고, 우리는 삽입된 삼원 연산자를 사용하여 액션 대상이 어떤 모양인지 확인한다.두 가지 형식의 유효 하중은 모두 같은 문자열이다.
그러나 리듀서가 문자열을 어떤 목록에 추가하는지 알기 위해서는 LANGUAGE가 null이 아닌 상황에서'ADD LANGUAGE'를 사용하고 FRAMEWORK가 null이 아닌 상황에서'ADD FRAMEWORK'를 사용해야 한다.
마지막으로, 우리는 방금 만든 조작을 보내고 목표 폼을 초기화합니다.
서브어셈블리 작업
그래서 다음 문제는 서브어셈블리를 어떻게 처리합니까?
redux에서, 우리는 상태의 관련 부분을 작업과 함께 하위 구성 요소에 전달할 수 있습니다.또한 MapStateTrops를 사용하여 각 구성 요소를 상태 관련 섹션에 직접 연결할 수도 있습니다.동작 작성자는 mapDispatchToProps를 사용하여 도구에 매핑할 수 있습니다.
useReducer를 사용하면 상태와 관련된 부분과 스케줄링 함수 자체를 제외하고는 어떤 내용도 전달하여 스케줄링을 할 필요가 없습니다.
우리 예를 하나 봅시다.
먼저 언어 및 프레임워크 섹션을 개별 구성 요소로 구분합니다.
const Languages = ({ languages, handleSubmit, dispatch }) => {
return (
<div>
<h3>Languages</h3>
<ul>
{languages.map((language, index) => {
return (
<li key={index}>
<b>{language}</b>
<button onClick={() => { dispatch({ type: 'REMOVE_LANGUAGE', payload: index }) }}>
Remove
</button>
</li>
)
})}
</ul>
<form onSubmit={handleSubmit}>
<input type='text' name='language' />
<input type='submit' value='Add Language' />
</form>
</div>
)
}
const Frameworks = ({ frameworks, handleSubmit, dispatch }) => {
return (
<div>
<h3>Frameworks</h3>
<ul>
{frameworks.map((framework, index) => {
return (
<li key={index}>
<b>{framework}</b>
<button onClick={() => { dispatch({ type: 'REMOVE_FRAMEWORK', payload: index }) }}>
Remove
</button>
</li>
)
})}
</ul>
<form onSubmit={handleSubmit}>
<input type='text' name='framework' />
<input type='submit' value='Add Framework' />
</form>
</div>
)
}
이제 이 코드는 별도의 구성 요소에서 추출되었으며 응용 프로그램 구성 요소의 JSX를 업데이트할 수 있습니다.return (
<div className="App">
<div>
<p><b>{state.name} </b>({state.occupation})</p>
<Languages languages={state.languages} handleSubmit={handleSubmit} dispatch />
<Frameworks frameworks={state.frameworks} handleSubmit={handleSubmit} dispatch/>
</div>
</div>
)
하위 구성 요소에서 상태를 업데이트하려면, 분배 함수만 전달해야 합니다.chid 구성 요소는 논리에서 적당한 조작을 조정할 것입니다.이것은 반드시 여러 개의 함수와 리셋을 전달해야 하는 것을 피할 수 있으며, 이러한 함수와 리셋은 곧 감당하기 어려워질 것이다.
useReducer의 장점
이제 use Reducer를 어떻게 실현하는지 알고 있습니다. 이 갈고리를 왜 사용하는지 토론해 봅시다.
1. 간단하다
첫 번째 이유는 우리가 전에 이미 토론한 것이 매우 간단하기 때문이다.이 갈고리는 Redux와 관련된 모든 템플릿 파일을 삭제합니다.레드ux 사용의 정당성을 증명하기 위한 규모가 부족한 프로젝트에 있어서 이것은 매우 귀중한 것이다.
2.useState보다 더 복잡한 상태 처리
만약 응용 프로그램의 상태가 여러 단계가 있다면,useState 갈고리를 사용하면 매우 지루해질 수 있습니다.이 문제를 해결하고 깨끗한 상태 관리 솔루션을 실현하기 위해use Reducer 갈고리가 이 임무에 더욱 적합하다.
3. 싫어하는 버팀목 구멍 줄이기
서브어셈블리에서 상태를 업데이트하는 방법 중 하나는 prop drilling이라는 기술을 사용하는 것입니다.
이것은 관련 구성 요소를 사용할 때까지 리셋 함수를 여러 단계로 전달하는 기술이다.
기술적으로 말하자면, 우리는 여전히 모든 부품을 통해 스케줄링 기능을 연습하고 있다.
그러나 분배 기능은 구성 요소가 알 수 없기 때문에 통과한 모든 구성 요소와 관련이 있을 수 있습니다.
4. 외부 라이브러리 종속성 삭제
Redux는 외부 라이브러리이기 때문에 react 프로젝트의 외부 의존 항목에 추가됩니다.
패키지 크기나 다른 원인에 대한 우려로 이 점을 깨닫게 된다면useReducer는 외부 패키지에 의존하지 않고 상당히 복잡한 상태를 관리하는 완벽한 방법입니다.
게시물How to Manage React State with useReducer이 가장 먼저Kelvin Mwinuka에 올라왔다.
만약 당신이 이 글을 좋아한다면, 나의 내용이 발표되기 전에 가능한 한 빨리 방문할 수 있도록 나를 따라오는 것을 고려할 수 있다. (걱정하지 마라. 그것은 여전히 무료이며, 짜증나는 팝업 광고가 없다.)또한 이 문장을 마음대로 평론해 주십시오.나는 너의 생각을 매우 듣고 싶다.
Reference
이 문제에 관하여(useReducer를 사용하여 React 상태 관리 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/kelvinvmwinuka/how-to-manage-react-state-with-usereducer-3o48텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)