React Redux è una libreria che fornisce i binding React per Redux.
I componenti di React che sono a conoscenza del negozio Redux sono chiamati "Containers", "Smart Components" o "Higher Order Component" (HOC). Tali componenti, per utilizzare Redux, devono:
Fare questo a mano implicherebbe l'uso di store.subscribe
e store.dispatch(action)
nei contenitori React.
React Redux semplifica il legame tra l'archivio Redux e un componente del contenitore React tramite la funzione connect
, che esegue il mapping delle proprietà dello stato Redux e dei creatori di azioni ai puntelli del componente.
connect
è una funzione che crea un componente di ordine superiore. Connect accetta 3 funzioni ( mapStateToProps
, mapDispatchToProps
, mergeProps
) e restituisce un componente contenitore, che avvolge il componente originale per trasformarlo in un componente "connesso":
import { connect } from 'react-redux';
const Customers = { ... };
const mapStateToProps = (state) => { ... }
const mapDispatchToProps = (dispatch) => { ... }
export default connect(mapStateToProps, mapDispatchToProps)(Customers);
Vedere la sezione degli esempi per un esempio completo.
Poiché tutti i componenti del contenitore devono accedere all'archivio Redux, il modo consigliato è utilizzare un componente <Provider>
speciale di React Redux, che passa l'archivio a tutti i componenti figli (internamente utilizzando il contesto React).
Documentazione ufficiale: http://redux.js.org/docs/basics/UsageWithReact.html
Resoconto GitHub: https://github.com/reactjs/react-redux
Versione | Data di rilascio |
---|---|
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 |
Supponiamo di avere il contenitore "CustomersContainer" che collega un componente stupido "Clienti" al negozio Redux.
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 CustomersContainer:
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 questa guida si presuppone che sia già stato installato react
, redux
, react-router
e react-redux
e averlo configurato react
, redux
e react-router
., Se non lo avete, si prega di farlo.
Nota: Mentre react-router
non è una dipendenza da react-redux
, è molto probabile che lo useremo nella nostra applicazione di reazione per il routing e questo rende davvero facile per noi usare react-redux.
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')
);
Questo file ha senso per la maggior parte di voi. Quello che stiamo facendo qui è ottenere il negozio da ./stores
e passarlo a tutte le rotte usando il Provider
componenti di ordine superiore fornito da react-redux
.
Questo rende il negozio disponibile in tutta la nostra applicazione.
Ora, consideriamo questo scenario . Abbiamo un componente UserComponent
che ottiene i dati dal riduttore user
e ha un pulsante che, una volta fatto clic, aggiorna i dati nel negozio.
Struttura dell'applicazione
Il nostro rootReducer
ha user
riduttore user
const rootReducer = combineReducers({
user: userReducer,
})
export default rootReducer;
Il nostro userReducer
questo aspetto
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;
E il nostro file di actions
un aspetto simile a questo
export function updateCurrentUserData( data ) {
return {
type: "UPDATE_CURRENT_USER_DATA",
payload: data
}
}
Finalmente, lavoriamo sul nostro componente
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;
Ovviamente questo non funzionerà , visto che non l'abbiamo ancora collegato al negozio.
Nel caso ve lo stiate chiedendo, questo è un componente funzionale stateless , dal momento che stiamo usando
redux
e non abbiamo davvero bisogno di uno stato interno per il nostro componente, questo è il momento giusto per usarlo.
Il metodo di connect
fornito da react-redux
accetta tre parametri
mapStateToProps , mapDispatchToProps e Component stesso.
connect( mapStateToProps, mapDispatchToProps )(Component)
Aggiungiamo connettività al nostro componente UserComponent insieme a mapStateToProps e mapDispatchToProps
E cerchiamo di aggiornare anche la nostra funzione changeUserDetails, così quando viene chiamato, Sarà dispatch
un action
ai nostri reducers
, e in base al tipo di azione il nostro riduttore entreranno in gioco e apportare modifiche al negozio, e una volta che il negozio ha aggiornato react-redux
si ri -Rendi il nostro componente con i nuovi dati.
Sembra complicato? Davvero non lo è.
Il nostro UserComponent.js
sarà simile
'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;
Quello che abbiamo fatto qui è stato aggiunto
mapStateToProps : questo ci consente di ottenere i dati dal negozio e quando tali dati cambiano, il nostro componente verrà rifatto con i nuovi dati.
Il nostro componente verrà riprodotto solo se i dati che il nostro componente richiede modifiche nello store e non quando altri dati cambiano nello store.
mapDispatchToProps : questo ci consente di dispatch actions
a tutti i riduttori dal nostro componente .. (potrebbe essere qualsiasi componente), E in base al type
di azione, il nostro utenteReducer eseguirà il kick-in e restituirà un nuovo stato con i dati aggiornati.
ConnectedUserComponent : Infine, abbiamo collegato il nostro componente allo store utilizzando il metodo connect
passando tutti i parametri ed exported
il componente connesso.
Abbiamo anche aggiornato la nostra funzione changeUserDetails di chiamare method
su oggetti di scena e passare anche nei dati., E props
, a sua volta invia il metodo abbiamo chiamato a tutti i riduttori.
NOTA:
react-redux
non ridisegnerà il nostro componente. L'utilizzo del redux
direttamente con la react
può sembrare un po 'difficile, come per ogni component
si desidera aggiornare quando si modificano gli store, è necessario sottoscrivere quel componente redux store
React Redux si prende cura di tutto questo e rende davvero facile scrivere componenti che possono richiedere i dati di cui ha bisogno dal redux store
e ricevere una notifica solo quando tali dati cambiano. Ciò ci consente di scrivere componenti veramente efficaci.
Per installare react-redux
tutto ciò che devi fare è eseguire questo comando npm
npm install --save react-redux
E hai finito.
Nota: React Redux dipende da