为什么会出现错误:'不应使用重复的密钥推送路由'使用React Native中的NavigationSt

Why getting an error: 'should not push route with duplicated key' with NavigationStateUtils in React Native?

本文关键字:密钥 路由 NavigationSt React 使用 中的 Native 错误 为什么      更新时间:2023-09-26

在我的React Native+Redux中,我为使用NavigationStateUtils进行导航设置了以下reducer:

import { PUSH_ROUTE, POP_ROUTE } from '../Constants/ActionTypes'
import { NavigationExperimental } from 'react-native'
import Login from '../Components/Login'
const {
  StateUtils: NavigationStateUtils
} = NavigationExperimental
const initialState = {
  index: 0,
  key: 'root',
  routes: [{
   key: 'login',
   title: 'Login',
   component: Login
  }]
}
function navigationState (state = initialState, action) {
  switch(action.type) {
    case PUSH_ROUTE:
      if (state.routes[state.index].key === (action.route && action.route.key)) return state
    return NavigationStateUtils.push(state, action.route)
    case POP_ROUTE:
      if (state.index === 0 || state.routes.length === 1) return state
      return NavigationStateUtils.pop(state)
   default:
     return state
  }
}
export default navigationState

还有一个按钮组件,它调用导航操作,如下所示:

  _handleBackAction() {
    if (this.props.navigation.index === 0) {
      return false
    }
    this.props.popRoute()
    return true
  }
  _handleNavigate(action) {
    switch (action && action.type) {
      case 'push':
        this.props.pushRoute(action.route)
        return true
      case 'back':
      case 'pop':
        return this._handleBackAction()
      default:
        return false
    }
  }
  render(){
    const route = {
      type: 'push',
      route: {
        key: this.props.navKey,
        title: this.props.pageName,
        component: this.props.componentName
      }
    }
    return(
      <TouchableHighlight onPress={() => this._handleNavigate(route)}>
        <Text style={styles}>{pr.pageName}</Text>
      </TouchableHighlight>
    )

我第一次按下按钮时,它导航正确,没有错误。但当我再次按下按钮时,我会得到以下错误:should not push route with duplicated key

我如何解决使用NavigationStateUtils在减速器中实现的问题?

提前谢谢!

您必须修改减速器才能进行推送。你需要做的是-

  1. 检查您必须推送的密钥路由是否已存在于堆栈中
  2. 如果没有,则在堆栈中推送该路由
  3. 如果它已经存在,那么找到它的索引,并对不包含重复路由的现有状态进行克隆
  4. 现在,您所要做的就是使用克隆状态更新您的状态。

     case PUSH_ROUTE:{
          // trying to push the route where we already are, no need to change a thing
              if (state.routes[state.index].key === (action.route && action.route.key)) 
                 return state;
          // ensure no duplicate keys
              const index = state.routes.findIndex((route) => {
              return action.route.key === route.key && action.route.title ===route.title;
             });
              if (index > -1) {
                       const clonedState = Object.assign({}, state);
                       clonedState.routes.splice(index, 1);
                       return NavigationStateUtils.push(clonedState, action.route);
                       }
           // normal case for a push
                 return NavigationStateUtils.push(state, action.route);
    

    }