분류 Reactjs

Redux (및 React-Redux)에 대한 유일한 소개 (3)

컨텐츠 정보

  • 조회 313 (작성일 )

본문

2 부 — 리액트 리덕스 


React 컴포넌트를 Redux와 연결하는 데 사용하는 react-redux라는 패키지가 있습니다.


React 프로젝트 디렉토리에서 터미널 창을 열고 다음 명령을 실행하여 Redux 및 React-Redux 패키지를 모두 설치할 수 있습니다.


npm i redux react-redux 


참고 :이 예제를 최대한 간단하게 유지하기 위해 이 프로젝트에는 가시성 필터를 구현하지 않습니다.


우선 React-Redux에 대해 알아야 할 두 가지가 있습니다.


1) React-Redux는 Provider라고 하는 React 구성 요소를 제공하므로 전체 응용 프로그램에서 응용 프로그램 저장소를 사용할 수 있습니다. 이는 index.js 파일에서 App을 Provider 구성 요소로 둘러싸고 스토어를 속성으로 공급자 구성 요소에 전달하여 수행됩니다.


// ...
import { Provider } from 'react-redux';
import store from './redux/store/store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
// ...


store은 이전에 작성한 store과 마찬가지로 일반 Redux store입니다.


2) React Redux는 연결 함수를 제공합니다. Redux에 컴포넌트를 "연결"할 때마다 이 함수를 사용합니다. 즉, React 컴포넌트가 Redux 스토어와 상호 작용하도록 합니다.


참고 : 거의 store에 직접 액세스하지 않습니다. 우리는 액션 제작자를 시작하고 나중에 모든 논리가 connect 함수에 의해 자동으로 처리됩니다.


이 함수는 실제로 상위 컴포넌트입니다. 컴포넌트의 클래스 이름을 제공하는 함수를 반환합니다 (나중의 예에서 connect 함수 뒤에 여분의 괄호에 주목).

또한 mapStateToProps 및 mapDispatchToProps라는 두 개의 선택적 인수를 사용합니다.


첫 번째 인수 인 mapStateToProps는 구성 요소의 속성에 store 값을 매핑하여 store에 가입하는 것과 관련이 있습니다. store을 구독하려는 경우 널이 아닌 첫 번째 인수를 제공합니다. 그렇지 않으면 store을 구독하지 않으려는 경우 첫 번째 인수로 null을 제공합니다.


두 번째 인수 인 mapDispatchToProps는 구성 요소 속성에 액션 생성자를 주입하는 것과 관련이 있습니다. 액션 제작자를 전혀 주입하지 않으려면 두 번째 인수로 null을 제공합니다.


mapStateToProps 


이것은 connect 함수의 첫 번째 인수입니다. 이름에서 알 수 있듯이 응용 프로그램 상태의 일부를 구성 요소의 실제 속성에 매핑합니다.

mapStateToProps는 실제로 앱의 전체 상태를 첫 번째 인수로 사용하여 구성 요소에 필요한 데이터 객체를 반환하는 함수입니다. 즉 첫 번째 매개 변수는 store.getState()와 같습니다.


mapStateToProps는 선택적 두 번째 인수를 사용하여 일부 구성 요소 props을 사용할 수 있습니다. store에서 데이터를 검색하기 위해 구성 요소의 props에서 추가 정보가 필요할 때 유용합니다.


(state, ownProps?) => stateProps 


mapStateToProps는 앱 상태가 변경되거나 (상태 매개 변수) ownProps 객체의 필드가 변경 될 때마다 호출됩니다. 또한 ownProps 또는 stateProps가 다르면 구성 요소가 다시 렌더링 되므로 항상 상태에서 최신 값을 가져옵니다.


mapDispatchToProps 


앞에서 언급했듯이 이 인수는 액션 제작자를 구성 요소의 props에 매핑 (주입)하는 데 사용됩니다.


mapDispatchToProps는 실제로 객체 또는 함수일 수 있습니다. 공식적인 React Redux 문서는 대부분의 시간 동안 당신이 겪을 일과 같이 정직하고 정직한 것을 권장합니다.


객체 인 경우 키가 구성 요소의 props에 매핑됩니다. 여기에서 액션 생성기 함수를 호출하여 새로운 메모를 상태로 유지할 수 있습니다.


import { addNote } from '../redux/actions/actions'; // we use this only when exporting
class NotesForm extends Component {
...
handleSubmission = (e) => {
...
let { title, content } = this.state;
this.props.addNote(title, content); // here we use the addNote from the component’s props
...
}
}
export default connect(
null, // mapStateToProps is null, we don’t care about what’s in the store nor we want to subscribe to it, because we simply dispatch an action from this component
{
addNote: addNote
} // mapDispatchToProps
)(NotesForm);


그러나 앞에서 언급했듯이 React에서 store에 직접 액세스하지 않으므로 store.dispatch()를 호출하지 않습니다. 우리는 액션 크리에이터를 호출하고 나머지는 connect 함수에 의해 마술처럼 처리됩니다.


“mapDispatchToProps가 객체가 아닌 함수라면 어떨까요? 언제 함수로 사용하고 싶습니까?” React-Redux 문서에서 이것을 인용하겠습니다.


“mapDispatchToProps를 함수로 정의하면 구성 요소가 받는 함수를 사용자 정의하고 조치를 전달하는 방법에 가장 유연합니다. 디스패치 및 ownProps에 액세스 할 수 있습니다. 이 기회를 이용하면 연결된 컴포넌트에서 호출 할 사용자 정의 함수를 작성할 수 있습니다.” 


dispatch와 store.dispatch는 실제로 같은 것이지만, 우리가 이미 알고 있듯이 ownProps는 컴포넌트를 만들 때 전달되는 컴포넌트 prop입니다.


mapDispatchToProps에 대해 강조하고 싶은 것이 하나 더 있습니다. 연결 함수에 두 번째 인수를 제공하지 않거나 mapDispatchToProps 함수에서 반환 한 객체가 디스패치 필드를 반환하면 구성 요소의 상자에서 디스패치 기능을 사용할 수 있습니다.

자세한 내용은 React Redux 설명서에서 이 링크를 방문하십시오.


React에서 Notes 앱 재작성 


이 예제에서는 create-react-app를 사용하여 이 간단한 응용 프로그램을 만듭니다.


Notes 구성 요소를 반환하기 위해 App 구성 요소를 다시 작성했습니다. Notes 컴포넌트는 NotesForm과 AllNotes라는 두 가지 컴포넌트를 더 렌더링 합니다.


Notes, AllNotes 및 NotesForm 구성 요소를 src/Notes 폴더에 보관합니다.


import React from 'react';
import Notes from './Notes/Notes';
function App() {
return (
<Notes />
);
}
export default App;


import React, { Component } from 'react'
import NotesForm from './NotesForm';
import AllNotes from './AllNotes';
export default class Notes extends Component {
render() {
return (
<React.Fragment>
<h1>React Redux Notes App</h1>
<NotesForm />
<hr />
<AllNotes />
</React.Fragment>
)
}
}


NotesForm 


이 구성 요소는 메모를 추가하기 위한 양식과 관련이 있습니다. 이 구성 요소는 새 메모를 추가하기 위해 조치를 상점에 발송합니다. 앱의 상태에 신경 쓰지 않고 구독 할 의사가 없으므로 첫 번째 매개 변수 (mapStateToProps)로 null을 제공합니다.


import React, { Component } from 'react';
import { connect } from 'react-redux';
import { addNote } from '../redux/actions/actions';
class NotesForm extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
content: ''
};
}
handleChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
handleSubmission = (e) => {
e.preventDefault();
let { title, content } = this.state;
this.props.addNote(title, content);
this.setState({ title: '', content: '' });
}
render() {
return (
<React.Fragment>
<h3>Add a Note</h3>
<form onSubmit={ this.handleSubmission }>
Title: <br />
<input type="text" name="title" value={ this.state.title } onChange={ this.handleChange } /><br />
Content: <br />
<textarea name="content" value={ this.state.content } onChange={ this.handleChange }></textarea><br />
<button type="submit">Add Note</button>
</form>
</React.Fragment>
)
}
}
export default connect(
null,
{
addNote: addNote
}
)(NotesForm);


그러나 두 번째 매개 변수 (mapDispatchToProps)의 경우, actions.js 파일에서 가져온 addNote 조치 작성기 함수를 맵핑하는 오브젝트를 제공합니다.


connect 함수는 마법을 수행하며 컴포넌트에서 this.props.addNote()를 호출하여 add add 조치를 상점에 전달합니다.


AllNotes 


Redux 상태로 저장된 모든 노트를 렌더링 하기 위해 이 컴포넌트를 사용할 것입니다. 마찬가지로 상태를 삭제하기 위한 작업을 파견해야 합니다. 다시 말해, 연결 기능에서 두 매개 변수를 모두 채워야 합니다.


간단히 말해서, 우리는 애플리케이션의 상태를 구독해야 합니다 (메모가 상태에서 노트가 추가되거나 삭제 될 때마다 즉시 표시되기를 원하기 때문에). 이것이 필요하기 때문에 deleteNote 액션을 컴포넌트의 props에 매핑해야 합니다. 메모를 삭제하기 위한 액션을 전달합니다.


import React, { Component } from 'react'
import { connect } from 'react-redux';
import { removeNote } from '../redux/actions/actions';
class AllNotes extends Component {
removeNote = (index) => {
this.props.removeNote(index);
}
render() {
const notesItems = this.props.notes.map((note, index) =>
<li key={ index }>
<b>{ note.title }</b>
<button onClick={ () => this.removeNote(index) }>x</button>
<br />
<span>{ note.content }</span>
</li>
);
return (
<React.Fragment>
<h3>All Notes</h3>
<ul>
{ notesItems }
</ul>
</React.Fragment>
)
}
}
const mapStateToProps = state => {
return {
notes: state.notes
};
};
const mapDispatchToProprs = {
removeNote: removeNote
};
export default connect(mapStateToProps, mapDispatchToProprs)(AllNotes);


두 번째 프로젝트도 마찬가지입니다. 여기 GitHub에서 찾을 수 있습니다.


결론 


Redux와 React Redux를 배우게 된 것을 축하합니다!


다음 단계로 공식 Redux 및 React Redux 문서를 방문하고 고급 가이드를 읽는 것이 좋습니다. 

Redux와 React Redux에 대해 더 깊이 이해할 수 있는 다음 추가 리소스를 고려할 수도 있습니다.


고려해야 할 자료 


  1. Redux Docs
  2. React-Redux Docs
  3. Dan Abramov ‘s course on EggHead
  4. Redux-related videos from Academind, The Net Ninja and Traversy Media
  5. Angular를 사용하는 경우 NgRxNGXS를 확인하십시오.