看例圖javascript
要求點擊組件一中的按鈕,改變組件二的背景色。java
利用state和props和容易實現。react
//app.js import React, {Component} from 'react'; import {StyleSheet, Button, View, Text} from 'react-native'; import TestView from './src/testView' export default class App extends Component { state = {bgColor:'red'}; changeBgc = () => { this.setState({bgColor:'yellow',}); setTimeout(()=>{this.setState({bgColor:'red',});},2000); } render() { return ( <View style={styles.container}> <Text>組件一</Text> <Button color="#841584" title="點我" onPress={this.changeBgc} /> <TestView bgColor={this.state.bgColor} /> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, }); //textView.js import React, {Component} from 'react'; import {Text, View} from 'react-native'; export default class TestView extends Component { render () { return ( <View style={{backgroundColor:this.props.bgColor,padding:50}}> <Text>組件二</Text> <Text>hello, redux</Text> </View> ); } }
再看下用redux的話怎麼作(方便起見,用最簡便的方法實現,實際項目不該該這麼寫)。redux
//app.js import React, {Component} from 'react'; import {createStore} from 'redux'; import {Provider} from 'react-redux' import {StyleSheet, Button, View, Text} from 'react-native'; import TestView from './src/testView' reducer = (state = {bgColor:'red'}, action) => { switch(action.type) { case 'change': return Object.assign({}, state, {bgColor:'yellow'}); case 'resume': return Object.assign({}, state, {bgColor:'red'}); default: return state; } } let store = createStore(reducer);//store管理app的全部state export default class App extends Component { changeBgc = () => { store.dispatch({type:'change'}); setTimeout(()=>{store.dispatch({type:'resume'});;},2000); } render() { return ( <Provider store={store}> <View style={styles.container}> <Text>組件一</Text> <Button color="#841584" title="點我" onPress={this.changeBgc} /> <TestView /> </View> </Provider> ); } } //textView.js import React, {Component} from 'react'; import {Text, View} from 'react-native'; import {connect} from 'react-redux'; class TestView extends Component { render () { return ( <View style={{backgroundColor:this.props.bgColor,padding:50}}> <Text>組件二</Text> <Text>hello, redux</Text> </View> ); } } //利用connect方法,把store中的屬性關聯到當前組件的props上 export default connect(state => ({ bgColor: state.bgColor, }))(TestView)
簡單講解下:store.dispatch做用相似setState,最終結果是更新state。不一樣的是,dispatch是經過觸發action (簡便起見,上面的代碼沒有使用action,而是直接模擬action返回的數據),根據action返回的數據和預先定義的reducer,來更新state。這裏須要注意的是Provider組件和connect方法,這兩個功能是react-redux插件提供的。使用Provider組件包裹app根組件,以後每一個組件中能夠經過connect方法將store.dispatch方法和指定屬性掛載到該組件的props屬性上。react-native
這樣,就用redux實現了以前代碼同樣的效果。但代碼看起來比以前更復雜了。app
別急,再看下這張例圖ide
要求點擊組件四中的按鈕,改變組件五中TextView的背景顏色。由於組件的嵌套,簡簡單單的一個效果一下變得複雜無比(須要state和回調層層傳遞)。flex
直接看下用redux如何實現this
//app.js import React, {Component} from 'react'; import {createStore} from 'redux'; import {Provider} from 'react-redux' import {StyleSheet, Text, View} from 'react-native'; import TestView from './src/testView'; import TestView1 from './src/testView1'; reducer = (state = {bgColor:'red'}, action) => { switch(action.type) { case 'change': return Object.assign({}, state, {bgColor:'yellow'}); case 'resume': return Object.assign({}, state, {bgColor:'red'}); default: return state; } } let store = createStore(reducer);//store管理app的全部state export default class App extends Component { render() { return ( <Provider store={store}> <View style={styles.container}> <Text>組件一</Text> <TestView /> <TestView1 /> </View> </Provider> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, }); //testView.js import React, {Component} from 'react'; import {Text, View} from 'react-native'; import SubButtonView from './subButtonView'; export default class TestView extends Component { render () { return ( <View style={{backgroundColor:'#ffffff',padding:20,}}> <Text>組件二</Text> <SubButtonView /> </View> ); } } //testView1.js import React, {Component} from 'react'; import {Text, View} from 'react-native'; import SubTextView from './subTextView'; export default class TestView1 extends Component { render () { return ( <View style={{backgroundColor:'#ffffff',padding:20,}}> <Text>組件三</Text> <SubTextView /> </View> ); } } //subButtonView.js import React, {Component} from 'react'; import {Button, View, Text} from 'react-native'; import {connect} from 'react-redux'; class SubButtonView extends Component { changeBgc = () => { this.props.dispatch({type:'change'}); setTimeout(()=>{this.props.dispatch({type:'resume'});},2000); } render () { return ( <View style={{backgroundColor:'#eeeeee',padding:20,}}> <Text>組件四</Text> <Button color="#841584" title="點我" onPress={this.changeBgc} /> </View> ); } } export default connect(state => ({ }))(SubButtonView) //subTextView.js import React, {Component} from 'react'; import {Text, View} from 'react-native'; import {connect} from 'react-redux'; class SubButtonView extends Component { render () { return ( <View style={{backgroundColor:'#eeeeee',padding:20,}}> <Text>組件五</Text> <Text style={{backgroundColor:this.props.bgColor,padding:20,}}>hello, redux</Text> </View> ); } } //利用connect方法,把store中的屬性關聯到當前組件的props上 export default connect(state => ({ bgColor: state.bgColor, }))(SubButtonView)
不難發現,使用redux,使react本來層層傳遞的狀態變得容易管理了。spa
固然redux還有其它特性和用法,能夠去redux官網瞭解。