React Redux is een bibliotheek die React-bindingen voor Redux biedt.
Reactcomponenten die zich bewust zijn van de Redux-winkel worden "Containers", "Smart Components" of "Higher Order Component" (HOC) genoemd. Dergelijke componenten, om Redux te gebruiken, moeten:
Als u dit handmatig doet, betekent dit dat u store.subscribe
en store.dispatch(action)
in React-containers gebruikt.
React Redux vereenvoudigt de binding tussen de Redux-store en een React-containercomponent door middel van de connect
functie, die Redux-statuseigenschappen en Action-makers toewijst aan de rekwisieten van de component.
connect
is een functie die een component van een hogere orde creëert. Connect accepteert 3 functies ( mapStateToProps
, mapDispatchToProps
, mergeProps
) en retourneert een containercomponent die de originele component omwikkelt om er een "verbonden" component van te maken:
import { connect } from 'react-redux';
const Customers = { ... };
const mapStateToProps = (state) => { ... }
const mapDispatchToProps = (dispatch) => { ... }
export default connect(mapStateToProps, mapDispatchToProps)(Customers);
Zie de voorbeeldensectie voor een volledig voorbeeld.
Omdat alle containeronderdelen toegang moeten hebben tot de Redux-winkel, is de aanbevolen manier om een speciale <Provider>
-component van React Redux te gebruiken, die de winkel doorgeeft aan alle onderliggende componenten (intern met React context).
Officiële documentatie: http://redux.js.org/docs/basics/UsageWithReact.html
GitHub repo: https://github.com/reactjs/react-redux
Versie | Publicatiedatum |
---|---|
5.0.3 | 2017/02/23 |
5.0.2 | 2017/01/11 |
5.0.1 | 2016/12/14 |
5.0.0 | 2016/12/14 |
4.4.6 | 2016/11/14 |
4.4.5 | 2016/04/14 |
4.4.4 | 2016/04/13 |
4.4.3 | 2016/04/12 |
4.4.0 | 2016/02/06 |
4.3.0 | 2016/02/05 |
4.2.0 | 2016/02/01 |
4.1.0 | 2016/01/28 |
4.0.0 | 2015/10/15 |
3.0.0 | 2015/09/24 |
2.0.0 | 2015/09/01 |
1.0.0 | 2015/08/24 |
0.5.0 | 2015/08/07 |
0.1.0 | 2015/07/12 |
Stel dat we een container 'Klantencontainer' hebben die een domme component 'Klanten' met de Redux-winkel verbindt.
In index.js:
import { Component }, React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import rootReducer from './redux/rootReducer';
import CustomersContainer from './containers/CustomersContainer';
let store = createStore(rootReducer);
render(
<Provider store={store}>
<CustomersContainer />
</Provider>,
document.getElementById('root')
);
In klantencontainer:
import React, { Component } from 'react';
import { connect } from 'react-redux';
// Import action creators
import { fetchCustomers } from '../redux/actions';
// Import dumb component
import Customers from '../components/Customers';
// ES6 class declaration
class CustomersContainer extends Component {
componentWillMount() {
// Action fetchCustomers mapped to prop fetchCustomers
this.props.fetchCustomers();
}
render() {
return <Customers customers={this.props.customers} />;
}
}
function mapStateToProps(state) {
return {
customers: state.customers
};
}
// Here we use the shorthand notation for mapDispatchToProps
// it can be used when the props and action creators have the same name
const CustomersContainer = connect(mapStateToProps, { fetchCustomers })(CustomersContainer);
export default CustomersContainer;
In deze gids wordt ervan uitgegaan dat je react
, redux
, react-router
en react-redux
hebt geïnstalleerd en react
, redux
en react-router
hebt geconfigureerd. Als je dat niet hebt gedaan, doe dat dan.
Opmerking: Hoewel react-router
niet afhankelijk is van react-redux
, is het zeer waarschijnlijk dat we het in onze react-applicatie zullen gebruiken voor routering en dit maakt het voor ons heel gemakkelijk om react-redux te gebruiken.
FILENAME: app.js
'use strict';
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, Link, browserHistory, IndexRoute } from 'react-router';
import { Provider } from 'react-redux';
import store from './stores';
render(
(
<Provider store={ store }>
<Router history={ browserHistory }>
{/* all the routes here */}
</Router>
</Provider>
),
document.getElementById('app')
);
Dit bestand zal voor de meesten van jullie logisch zijn. Wat we hier doen, is de winkel ./stores
van ./stores
en deze doorgeven aan alle routes met behulp van Higher Order Component Provider
van react-redux
.
Hierdoor is de winkel overal in onze applicatie beschikbaar.
Laten we dit scenario eens bekijken . We hebben een component UserComponent
die de gegevens uit het user
haalt en heeft een knop die, wanneer erop wordt geklikt, de gegevens in de winkel bijwerkt.
Applicatie structuur
Onze rootReducer
heeft user
const rootReducer = combineReducers({
user: userReducer,
})
export default rootReducer;
Onze userReducer
ziet er zo uit
const default_state = {
users: [],
current_user: {
name: 'John Doe',
email: 'john.doe@gmail.com',
gender: 'Male'
},
etc: {}
};
function userReducer( state=default_state, action ) {
if ( action.type === "UPDATE_CURRENT_USER_DATA" ) {
return Object.assign( {}, state, { current_user: Object.assign( {}, state.current_user, { [action.payload.field]: action.payload.value } ) } );
}
else {
return state;
}
}
export default userReducer;
En ons actions
ziet er ongeveer zo uit
export function updateCurrentUserData( data ) {
return {
type: "UPDATE_CURRENT_USER_DATA",
payload: data
}
}
Eindelijk, laten we werken aan onze component
FILENAME: UserComponent.js
'use strict';
import React from 'react';
import { connect } from 'react-redux';
import * as Action from './actions';
let UserComponent = (props) => {
let changeUserDetails = (field, value) => {
// do nothing
}
return(
<div>
<h1>Hello { props.current_user.name }</h1>
<p>Your email address is { props.current_user.email }</p>
<div style={{ marginTop: 30 }}>
<button onClick={ () => { changeUserDetails('name', 'Jame Smith') } }>Change Name</button>
<button onClick={ () => { changeUserDetails('email', 'jane@gmail.com') } }>Change Email Address</button>
</div>
</div>
)
}
export default UserComponent;
Natuurlijk zal dit niet werken , omdat we het nog niet met de winkel hebben verbonden.
Voor het geval je je dit afvraagt, is dit een stateless functionele component , omdat we
redux
en we niet echt een interne status voor onze component nodig hebben, is dit het juiste moment om het te gebruiken.
De connect
van react-redux
heeft drie parameters
mapStateToProps , mapDispatchToProps en de component zelf.
connect( mapStateToProps, mapDispatchToProps )(Component)
Laten we connect toevoegen aan onze component UserComponent, samen met mapStateToProps en mapDispatchToProps
En laten we ook onze functie changeUserDetails bijwerken, dus wanneer deze wordt aangeroepen, dispatch
een action
naar onze reducers
, en op basis van het type actie zal onze reducer in werking treden en wijzigingen aanbrengen in de winkel, en zodra de winkel bijgewerkte react-redux
opnieuw -lever onze component met de nieuwe gegevens.
Klinkt ingewikkeld? Dat is het echt niet.
Onze UserComponent.js
zal eruit zien
'use strict';
import React from 'react';
import { connect } from 'react-redux';
import * as Action from './actions';
const mapStateToProps = ( state, ownProps ) => {
return {
current_user: state.user.current_user,
}
}
const mapDispatchToProps = ( dispatch, ownProps ) => {
return {
updateCurrentUserData: (payload) => dispatch( Action.updateCurrentUserData(payload) ),
}
}
let UserComponent = (props) => {
let changeUserDetails = (field, value) => {
props.updateCurrentUserData({ field: field, value: value });
}
return(
<div>
<h1>Hello { props.current_user.name }</h1>
<p>Your email address is { props.current_user.email }</p>
<div style={{ marginTop: 30 }}>
<button onClick={ () => { changeUserDetails('name', 'Jame Smith') } }>Change Name</button>
<button onClick={ () => { changeUserDetails('email', 'jane@gmail.com') } }>Change Email Address</button>
</div>
</div>
)
}
const ConnectedUserComponent = connect(
mapStateToProps,
mapDispatchToProps
)(UserComponent)
export default ConnectedUserComponent;
Wat we hier deden is toegevoegd
mapStateToProps : hiermee kunnen we de gegevens uit de winkel halen en wanneer die gegevens veranderen, wordt onze component opnieuw weergegeven met de nieuwe gegevens.
Onze component wordt alleen opnieuw weergegeven als de gegevens waarvoor onze component wijzigingen in de winkel aanvraagt en niet wanneer andere gegevens in de winkel worden gewijzigd.
mapDispatchToProps : Dit stelt ons in staat om dispatch actions
te dispatch actions
naar alle reductiemiddelen van onze component ... (kan elke component zijn), en op basis van het type
actie, zal onze userReducer ingaan en een nieuwe status retourneren met de bijgewerkte gegevens.
ConnectedUserComponent : Ten slotte hebben we onze component met de winkel verbonden via de connect
methode door alle parameters door te geven en de verbonden component exported
.
We hebben ook onze functie changeUserDetails bijgewerkt om de method
op props aan te roepen en ook de gegevens door te geven. En props
verzendt op zijn beurt de methode die we naar alle reducers hebben aangeroepen.
NOTITIE:
react-redux
onze component niet opnieuw weergeven. Met behulp van redux
direct met react
lijkt misschien wat moeilijk, net als voor elke component
die u wilt bijwerken wanneer er wijzigingen op te slaan, moet je die component abonneren op de redux store
React Redux zorgt voor al deze en maakt het heel eenvoudig om componenten te schrijven die de benodigde gegevens kunnen opvragen bij redux store
en alleen op de hoogte te worden gebracht wanneer die gegevens veranderen., Hiermee kunnen we echt effectieve componenten schrijven.
Om react-redux
te installeren react-redux
om deze npm
opdracht uit te voeren
npm install --save react-redux
En je bent klaar.
Opmerking: React Redux is afhankelijk van