使用 React Redux 的 Hello World
本指南假設你已經安裝了 react
,redux
,react-router
和 react-redux
並配置了 react
,redux
和 react-router
。如果還沒有,請這樣做。
注意: 雖然 react-router
不是 react-redux
的依賴關係,但我們很可能會在我們的路由反應應用程式中使用它,這使我們很容易使用 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')
);
這個檔案對大多數人來說都是有意義的,我們在這裡做的是從 ./stores
獲取商店並使用 react-redux
提供的高階元件 Provider
將其傳遞到所有路線。
這使得商店在整個應用程式中都可用。
現在,讓我們考慮一下這種情況。我們有一個元件 UserComponent
,它從 user
reducer 獲取資料,並有一個按鈕,點選該按鈕更新商店中的資料。
應用結構
我們的 rootReducer
有 user
減速機
const rootReducer = combineReducers({
user: userReducer,
})
export default rootReducer;
我們的 userReducer
看起來像這樣
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;
我們的 actions
檔案看起來像這樣
export function updateCurrentUserData( data ) {
return {
type: "UPDATE_CURRENT_USER_DATA",
payload: data
}
}
最後,讓我們在我們的元件上工作
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;
當然這不起作用,因為我們尚未將它連線到商店。
如果你想知道,這是一個無狀態功能元件,因為我們使用
redux
並且我們並不真正需要元件的內部狀態,這是使用它的正確時間。
react-redux
提供的 connect
方法有三個引數
mapStateToProps , mapDispatchToProps 和 Component 本身。
connect( mapStateToProps, mapDispatchToProps )(Component)
讓我們新增連線到我們的元件 UserComponent 以及 mapStateToProps 和 mapDispatchToProps
而且我們還要更新我們的 changeUserDetails 函式,所以當呼叫它時,它將根據我們的 reducers
的 action
,並根據我們的 reducer 將啟動並對商店進行更改的動作型別,一旦商店更新,react-redux
將重新渲染我們的元件包含新資料。
聽起來很複雜?它真的不是
我們的 UserComponent.js
看起來像
'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;
我們在這裡做了什麼
-
mapStateToProps :這使我們能夠得到儲存和當資料是資料的變化,我們的元件將被重新渲染與新的資料。
我們的元件只會在我們的元件請求更改商店的資料時重新呈現,而不會在商店中的任何其他資料更改時重新呈現。
-
mapDispatchToProps :這允許我們將
dispatch actions
傳送到我們元件中的所有 reducers …(可以是任何元件),並且基於動作的type
,我們的 userReducer 將啟動並返回具有更新資料的新狀態。 -
ConnectedUserComponent :最後,我們使用
connect
方法將我們的元件連線到商店,方法是將所有引數和exported
傳遞給連線的元件。 -
我們還更新了我們的 changeUserDetails 函式,在 props 上呼叫
method
並傳入資料。然後props
將呼叫我們呼叫的方法排程到所有 reducers。
注意:
- 如果我們不從 reducer 返回一個新狀態,
react-redux
將不會重新渲染我們的元件。