在 RN 中如何使用 React-Redux
其實,在 RN 中使用 React-Redux 和 React 中類似,可以說一模一樣
都是在根元素中使用,<Provider>
來包裹根組件,導入 store,將 store 掛載在 Provider
上。
代碼的結構:
.
├── src # 程序源文件夾
│ ├── pages # 主要的頁面,文件夾
│ ├── navigation # 頁面的導航,文件夾
│ ├── redux # redux,文件夾
│ └── App.js # 根組件,文件
└── index.js # 程序入口文件
index.js 代碼:
import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
App.js 代碼:
import React, {Component} from 'react';
import store from './redux/store';
import AppNavigation from './navigation/AppNavigation';
import {Provider} from 'react-redux';
export default class App extends Component {
render() {
return (
<Provider store={store}>
<AppNavigation />
</Provider>
);
}
}
其中 AppNavigation 是導航(react-navigation)
AppNavigation.js 代碼:
import {createAppContainer} from 'react-navigation';
import {
createStackNavigator,
StackViewStyleInterpolator, // 這個是一個頁面的彈出的方向,安卓默認是從下到上,這個就將方向改爲從左往右
} from 'react-navigation-stack';
import Book from '../pages/'; // 如果你的文件名爲 index.js 會默認加載這個文件
import Add from '../pages/otherPage/add';
import AlterColor from '../pages/otherPage/alterColor';
const stack = createStackNavigator(
{
Book: {
screen: Book,
navigationOptions: {
header: null,
},
},
Add: {
screen: Add,
},
AlterColor: {
screen: AlterColor,
},
},
{
transitionConfig: () => ({
screenInterpolator: StackViewStyleInterpolator.forHorizontal,
}),
},
);
export default createAppContainer(stack);
pages 文件夾的結構:
├── index.js
└── otherPage
├── add.js
└── alterColor.js
index.js 代碼:
主要是對 store 中的數據進行操作,而後在 add.js 和 altercolor.js 中看結果
import React, {Component} from 'react';
import {TextInput, Button, View, StyleSheet, Text} from 'react-native';
import {connect} from 'react-redux';
import {addCreator, alterColorCreator} from '../redux/actionCreator/test';
class Index extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
};
}
render() {
const {navigation} = this.props;
return (
<View style={styles.container}>
<View style={styles.margin}>
<TextInput
onChangeText={value => {
this.setState({
inputValue: value,
});
}}
style={styles.input}
/>
</View>
<View style={styles.margin}>
<Button
onPress={() => {
this.props.alterColor(this.state.inputValue);
}}
color="#841584"
title={'確認更改color'}
/>
</View>
<View style={styles.margin}>
<Button
title={'+1'}
onPress={() => {
this.props.add();
}}
/>
</View>
<View style={styles.margin}>
<Button
title={'跳轉到add頁面'}
onPress={() => {
navigation.navigate('Add');
}}
/>
</View>
<View style={styles.margin}>
<Button
onPress={() => {
navigation.navigate('AlterColor');
}}
title={'跳轉到alterColor頁面'}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
},
input: {
borderColor: '#000',
borderBottomWidth: 1,
width: 300,
},
margin: {
marginTop: 10,
width: 300,
},
});
const mapDispatchToProps = (dispatch, ownProps) => {
return {
add: () => {
dispatch(addCreator());
},
alterColor: color => {
dispatch(alterColorCreator(color));
},
};
};
const mapStateToProps = (state, ownProps) => {
const {color, number} = state.test;
return {
color: color,
number: number,
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Index);
使用 connect 將 mapStateToProps 屬性,mapDispatchToProps 方法,掛載到 Index 的 props 屬性上
add.js 代碼:
import React, {Component} from 'react';
import {View, Text} from 'react-native';
import {connect} from 'react-redux';
class AlterColor extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<Text>{this.props.number}</Text>
</View>
);
}
}
const mapStateToProps = (state, ownProps) => {
const {color, number} = state.test;
return {
color: color,
number: number,
};
};
export default connect(
mapStateToProps,
null,
)(AlterColor);
alterColor.js 代碼:
import React, {Component} from 'react';
import {View, Text} from 'react-native';
import {connect} from 'react-redux';
class AlterColor extends Component {
constructor(props) {
super(props);
console.log(props);
}
render() {
return (
<View>
<Text style={{backgroundColor: this.props.color}}>Color</Text>
</View>
);
}
}
const mapStateToProps = (state, ownProps) => {
const {color, number} = state.test;
return {
color: color,
number: number,
};
};
export default connect(
mapStateToProps,
null,
)(AlterColor);
redux 文件目錄:
store.js 代碼:
/**
* 創建倉庫(store)
*/
import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducer/rootReducer';
export default createStore(rootReducer, applyMiddleware(thunk));
注:redux-thunk 如果需要異步的操作的話使用
/reducer/test.js 代碼:
/**
* 測試一下 reducer
*/
const defaultState = {
color: 'green',
number: 1,
};
import {ADD, ALTER_COLOR} from '../actionTypes/test';
export default (state = defaultState, action) => {
let newState = JSON.parse(JSON.stringify(state));
switch (action.type) {
case ALTER_COLOR:
newState.color = action.color;
return newState;
case ADD:
newState.number++;
return newState;
}
return state;
};
/actionTypes/test.js 代碼:
export const ALTER_COLOR = 'alter_color';
export const ADD = 'add';
/actionCreator/test.js 代碼:
import {ADD, ALTER_COLOR} from '../actionTypes/test';
export const addCreator = () => {
return {
type: ADD,
};
};
export const alterColorCreator = color => {
return {
type: ALTER_COLOR,
color,
};
};
效果圖:
index.js
點擊兩次 +1
,跳轉到 Add 頁面
inputValue 中輸入 #000
,跳轉到 alterColor 頁面
總結完畢:
參考資料:
- react-reudx官方:https://redux.js.org/basics/usage-with-react