React Native - Redux:app

时间:2016-10-13 13:57:31

标签: android reactjs react-native redux react-router

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

例如,假设在应用程序中前进,我将在下面进行导航。 enter image description here

返回导航时,

enter image description here

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

以下是上述示例的代码,

Page.js [Component]

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;
    }
}

我的观察:每当导航中出现同一页面并且该页面的商店中的状态发生变化时,它会调用该页面的 mapStateToProps()页面的次数在导航堆栈中。因此,它会循环遍历该页面的生命周期方法,以根据最新状态更改状态 在此示例中,当我点击抽屉中的香蕉时,会将商店中的状态从芒果更改为香蕉 mapStateToProps()被调用3次(因为该页面在导航堆栈中存在3次)因此所有从componentWillReceiveProps()到componentDidUpdate()的生命周期反应方法被调用3次只是为了改变根据最新州的那个页面的状态

我想要的东西:我希望导航中的页面状态不同,所以回过头来我可以看到我访问过的所有不同的产品。

根据redux架构的问题很明显,但我没有得到解决它的技巧。任何帮助或任何其他工作来实现我的目标将不胜感激。

2 个答案:

答案 0 :(得分:1)

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

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

在mapStateToProps函数中,首先提取当前选择,这必须是一个标识符。您也可以从其他地方提取它,例如从组件道具(mapStateToProps的第二个参数)。然后使用该提取的标识符从域数据存储中获取已加载的数据。如果选择的数据不在商店中(例如,当用户第一次访问页面时,或者它已经被垃圾收集),则将空值放入props中,这将意味着componentDidMount或componentWillReceiveProps挂钩他们必须发出一个数据加载请求(它可以实现为一个动作的调度,根据你用于管理数据加载的内容,向一个传奇或一个thunk发出数据需求的信号),而这就发生了返回一些&#34; loading ...&#34;存根。当请求完成时,另一个调度将更新域数据存储更新,这将触发连接以进行另一个mapStateToProps调用,这将导致发现所选数据已存在于存储中,因此不会进行新的数据加载请求,渲染将有足够的数据供显示。

答案 1 :(得分:-1)

仅使用Redux无法完成您要做的事情。

您需要在浏览器或应用中记录导航更改时的更改。 HistoryJS用于做到这一点。 react-router使用此模块在Web导航中提供了良好的用户体验。

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

我不知道react-router如何对原生应用做出反应,所以看看React Native Router。它提供了handle navigation with Redux on native app的方法。