家喻户晓,React中数据通信是单向的,即父组件能够通过props向子组件传递数据,而子组件却不能向父组件传递数据。要实现子组件向父组件传递数据的需要,须要父组件提供一个批改数据的办法,当页面越来越多的时候,数据的治理就会变得异样简单。
并且,每次数据的更新都须要调用setState,特地是波及到跨组件通信的问题就会很麻烦。在React开发中,为了解决跨组件通信的问题,业界开发了一大批状态治理框架,目前比拟罕用的React状态治理框架有Flux、Redux和Mobx等几个。
其中,Flux是Facebook用于建设客户端Web利用的前端架构,它利用一个单向数据流的形式补充了React的组合视图组件,解决了MVC技术架构中数据流管理混乱的问题。Redux则是由Dan Abramov开源的一款前端状态治理框架,Redux框架由Action、Store和Reducers三局部组成,所有组件的数据都存储到Store对象中,每个组件只须要扭转Store中的数据,当Store数据发生变化时就会其余订阅的组件执行数据更新。Mobx是一个面向对象的状态治理框架,它与Redux的最大区别是能够间接批改数据,精准的告诉UI进行刷新,而不是Redux的播送。
能够发现,Redux特地适宜用在须要集中式治理数据场景中。多个组件应用同一个数据源,保护同一个数据样本,进而放弃各个组件之间数据的一致性。react-redux是Redux状态框架在React中的技术实现,对于相熟Redux状态治理框架开发者来说,学习react-redux将会显得非常容易。
在Redux状态框架中,Redux将状态治理分为Action、Store和Reducers三局部。其中,Redux将应用程序的状态存储到Store中,组件通过dispatch()办法触发Action,Store接管Action并将Action转发给Reducer,Reducer依据Action类型对状态数据进行解决并将处理结果返回给Store,其余组件通过订阅Store状态的来刷新本身的状态,整个框架的工作流程如图3-9所示。


上面以计数器为例来阐明Redux的根本应用。首先,创立一个action.js文件,用来寄存Action行为事件,如下所示。

export const ADD = 'ADD'export const MINUS = 'MINUS'

而后,创立一个reducer.js文件,用来解决业务逻辑的更新,并将解决的后果返回给Store,如下所示。

import {ADD, MINUS} from './action';function reducer (state = {count: 0}, action) {    switch(action.type) {        case ADD:            return {count: state.count + 1}        case MINUS:            return {count: state.count - 1}        default:            return state    }}export default reducer;

Reducer是一个纯函数,接管State和Action两个参数。其中,State是旧的状态,不能够间接批改,Reducer会依据Action的类型来生成不同的新State,并将后果返回给Store。
接下来,创立一个全局的Store对象,用来寄存利用的状态数据,创立时须要应用Store提供的createStore()办法,如下所示。

import { createStore } from 'redux'import reducer from './reducer';const store = createStore(reducer)export default store

除了createStore()办法外,创立的Store还有以下几个办法能够调用。

  • getState():获取最新的状态数据。
  • dispatch():派发Action行为事件。
  • subscribe():订阅Store中的状态变动。

为了实现计数器加减的性能,还须要在组件的生命周期函数中增加订阅事件,并在组件销毁时解决订阅,如下所示。

class CounterPage extends React.Component {    constructor(props){        super(props)        this.state = {            number: store.getState().count        }    }    componentDidMount () {        this.unSubscribe = store.subscribe(() => {            this.setState({                number: store.getState().count            })        })    }    componentWillUnmount () {        this.unSubscribe && this.unSubscribe()    }    render() {        return (            <View style={styles.ct}>                <Text>{this.state.number}</Text>                <Button                    title="加1"                    onPress={() => store.dispatch({type: 'ADD'})}/>                <Button                    title="减1"                    onPress={() => store.dispatch({type: 'MINUS'})}/>            </View>        );    }}const styles = StyleSheet.create({    ct: {        flex: 1,        justifyContent: 'center',        alignItems: 'center',    },});export default CounterPage;

在下面的代码中,咱们通过store.getState()办法来获取最新的State,而执行加减操作时通过store.dispatch()办法派发Action给Store。能够发现,在类组件中应用Redux还是挺繁琐的,须要开发者本人治理组件的状态数据,而如果改用React Hook就要简略许多。
在React Hook中应用Redux须要应用react-redux库提供的useSelector()与useDispatch()两个函数。其中,useSelector()函数能够用来获取状态值,而useDispatch()则能够用来批改状态数据,如下所示。

import { useSelector, useDispatch } from 'react-redux'const CounterPage = () => {        const count = useSelector(state => state.count)    const dispatch = useDispatch()    return (        <View style={styles.ct}>            <Text>{count}</Text>            <Button                title='加1'                onPress={() => dispatch({type: 'ADD'})}/>            <Button                title='减1'                onPress={() => dispatch({type: 'MINUS'})}/>        </View>    );}const styles = StyleSheet.create({    …. //省略代码});export default CounterPage

能够发现,相比于类组件来说,应用React Hook实现就要简洁许多。首先,咱们应用useSelector()函数获取Store中的状态,而后再应用useDispatch()函数派发事件。
最初,应用Redux在让不同组件之间共享状态数据时,还须要应用react-redux库提供的Provider包裹利用组件,如下所示。

const App = () => {    return (        <Provider store={store}>            <CounterPage />        </Provider>    );};

从新运行代码,就实现了计数器的性能,如下图所示。

最初,须要阐明的是,应用Redux进行状态治理时,应留神以下几点:
• 利用中有且仅有一个Store,该Store存储了整个利用的状态。
• State是只读的,批改State只能通过派发Action事件,为了形容Action扭转State的过程,须要应用Reducer纯函数。
• 繁多数据源让多个React组件之间的通信更加不便,也有利于状态的对立治理。