React Native - Redux:应用程序中相同状态的多个实例

Posted

技术标签:

【中文标题】React Native - Redux:应用程序中相同状态的多个实例【英文标题】:React Native - Redux : Multiple instances of same state in app 【发布时间】:2017-02-22 16:49:32 【问题描述】:

我是 React Native 的新手。我正在为我的 react native 应用程序使用 redux 架构,但是由于 redux 的全局存储状态,我遇到了问题。

假设例如,前进时在应用程序中,我正在如下导航。

返回导航时,

根据 redux 架构,它将导航堆栈中存在的每个页面实例的状态更改为商店中的最新状态。

这是上面例子的代码,

Page.js [组件]

class Page extends Component

    componentWillMount()

    

    render()
        var image,apiCall = this.props;

        return (
        <View>
            <Image Source=uri:image style=// style for the image>
        </View> 
    )

    componentDidMount()
        this.props.apiCall(this.props.route.data.link);   // this.props.route.data.link -> this is just a link for                                                  // the apiCall
    

    componentWillReceiveProps()

    

    shouldComponentUpdate(nextProps, nextState)
        if(this.props.image==nextProps.image)
          return false;
        
        return true;
    

    componentWillUpdate()

    

    componentDidUpdate()

    

    componentWillUnmount()

    


   const mapStateToProps = (state) => 
     return 
     image: state.PageDataReducer.image
     ;
   ;

   const mapDispatchToProps = (dispatch) => 
     return 
       apiCall: (link) => 
         dispatch(fetchProduct(link));  // fetchProduct() -> is a function which fetches the product from the                                  // network and dispatches the action.
       ,
     ;
   ;

export default connect(mapStateToProps,mapDispatchToProps)(Page);

fetchProduct() [获取产品的函数]

export function fetchProduct(link) 
  return function(dispatch)
    // fetches the product over network
    dispatch(fetchedProduct(productLink));
  

fetchedProduct [操作]

export const fetchedProduct = (productLink) =>   
  return 
    type: FETCHED_PRODUCT,
    image: image
  ;
;

PageDataReducer [Reducer]

export default function PageDataReducer(state = initialState, action) 

   switch (action.type) 

    case FETCHED_PRODUCT:
    var newState = 
      ...state,
      image: action.image
    ;
      return newState;

    default:
      return state;
    

我的观察:每当导航中出现相同的页面并且该页面的商店中的状态发生变化时,它就会调用该页面的 ma​​pStateToProps() 该页面的次数位于导航堆栈中。因此,它循环通过该页面的生命周期方法以根据最新状态更改状态的次数。在此示例中,当我单击香蕉时 在抽屉中,它将商店中的状态从芒果更改为香蕉,并且 ma​​pStateToProps() 被调用 3 次(因为该页面在导航堆栈中出现了 3 次) 因此从 componentWillReceiveProps() 到 componentDidUpdate() 的所有响应生命周期方法都被调用了 3 次,只是为了根据最新状态更改该页面的状态

我想要什么:我想要导航中页面的不同状态,以便在返回时可以看到我访问过的所有不同产品。

根据 redux 架构,问题很明显,但我没有解决它的窍门。为实现我的目标而提供的任何帮助或任何其他工作将不胜感激。

【问题讨论】:

你能澄清你的问题吗? @DamienLeroux,是的,我已经在上面编辑了我的问题。你能再看一遍吗? 您说“根据 redux 架构,它正在将导航堆栈中存在的每个页面实例的状态更改为商店中的最新状态。”如果没有将每个应用程序状态保存在某处的代码,redux 架构就不会这样做。可能是你的问题 【参考方案1】:

您应该将域数据的存储(例如关于苹果、芒果和香蕉的数据)与 UI 状态的存储(例如当前选择的项目)分离。在域数据部分,您将存储所有已加载的项目(您可能希望稍后添加一些垃圾收集策略,例如最近最少使用的列表以节省一些内存)。

然后视图组件将连接到应用状态树的两个部分:连接到 UI 部分以获取当前选择的内容,并连接到域部分以获取有关所选项目的详细信息。

在您的 mapStateToProps 函数中,首先提取当前选择,这必须是一个标识符。您也可以从其他地方提取它,例如来自组件道具(mapStateToProps 的第二个参数)。然后,您使用该提取的标识符从域数据存储中获取已加载的数据。如果选择的数据不在存储中(例如,当用户第一次访问页面时,或者它已经被垃圾收集),你将空值放入 props,这意味着 componentDidMount 或 componentWillReceiveProps 钩子他们必须提出数据加载请求(它可能被实现为一个动作的分派,该动作向 saga 或 thunk 发出数据需求信号,具体取决于您用于管理数据加载的内容),而在这种情况下,渲染会返回一些“正在加载...”存根。当请求完成时,另一个 dispatch 会更新域数据存储更新,这将触发 connect 进行另一个 mapStateToProps 调用,这将导致发现所选数据已经在存储中,因此不会发出新的数据加载请求,并且渲染将有足够的数据进行显示。

【讨论】:

【参考方案2】:

你想要做的事情不能只用 Redux 来完成。

您需要在浏览器或应用程序中记录您在导航更改时所做的更改。 HistoryJS 用于执行此操作。 react-router 使用此模块在网络导航中提供良好的用户体验。

所以要么使用react-router 声明不同的页面(每个水果一个),或者至少使用HistoryJS 以编程方式保存导航状态。

我不知道 react-router 对本机应用程序的反应如何,请查看 React Native Router。它提供了一种handle navigation with Redux on native app 的方法。

【讨论】:

是的,实际上我尝试使用 react-native-router-flux 库,甚至使用 react native 的 navigational experimental 组件。但没有奏效。问题是由于 redux 架构造成的。如果我以正常状态(而不是 redux)执行此操作,它当然可以正常工作。但是对一些组件使用 state 对一些组件使用 redux 是否很好?如果是,那么不同组件的状态是否可以在整个应用程序中进行管理? 没有严格使用一个或另一个的规则。你可以同时使用 redux 和组件状态,这取决于你想要做什么。组件状态不能在整个应用程序中进行管理。

以上是关于React Native - Redux:应用程序中相同状态的多个实例的主要内容,如果未能解决你的问题,请参考以下文章

使用 react-redux 与 react-native 连接时的不变违规

使用 redux 在 react-native 应用程序中保存访问令牌的最佳实践是啥?

在 React Native 应用程序中将 Relay 与 Redux 集成

React native 和 redux 仍然无法正常工作

无法识别的事件 React Native Redux

在 Redux 中没有 React Navigation 状态的 React Native 中的 Redux