Redux 和 NavigatorIOS 不会更新本机子视图中的状态?

Redux & NavigatorIOS does not update state in child views in react-native?

如何使 NavigatorIOS 中包含的 redux 更新主视图和详细视图?

主视图和详细视图都没有更新:

MainView > TabBar > TabBarItem > NavigatorIOS > MasterMenu > Detail

其他 TabBarItem 使用 redux 效果很好。例如:

MainView > TabBar TabBarItem > ViewProfile

  <Icon.TabBarItem
  style={{borderColor:'red', borderWidth:0}}
  {...this.props}
  iconName="timeline"
  title="View"
  selected={this.state.selectedTab === 'viewTab'}
  onPress={() => {
    this.setState({
      selectedTab: 'viewTab',
      presses: this.state.presses + 1
    });
  }}>
  <ViewProfile {...this.props} />
  </Icon.TabBarItem>

这个 MainView > TabBar > TabBarItem > NavigatorIOS > MasterMenu > Detail NOT 更新:

<Icon.TabBarItem
style={{borderColor:'red', borderWidth:0}}
title={'Menu'}
iconName="more-vert"
selected={this.state.selectedTab === 'moreTab'}
onPress={() => {
  this.setState({
    selectedTab: 'moreTab',
  });
}}>
<View style={ss.container}>
<NavigatorIOS
ref="nav"
style={ss.container}
{...this.props}
initialRoute={{
  title: 'Master Menu',
  component: MasterMenu,
  passProps: {
    ...this.props,
  },
}}
/>
</Icon.TabBarItem>

</TabBarIOS>

这就是我连接道具并将其传递给包含 NaigatorIOS > MasterMenu > Detail

MainView 的方式

文件:mainApp.js

class MainApp extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log('****** MainApp::render ****');
    const { state, actions } = this.props;
    return (
      <MainView
        {...this.props} />
    );
  }
}

// mapStateToProps
function mapStoreStateToComponentProps(state) {
  return {
    state: state.appState,
  };
}
function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(Object.assign({}, appActions), dispatch),
  }
}
export default connect(
  mapStoreStateToComponentProps,
  mapDispatchToProps
)(MainApp)

我可以深入到包含 MasterMenu->DetailMenu 视图的 NavigatorIOS,在详细视图中调用操作,状态更改以及 TabBarIOS 中的所有其他视图更新。但是,<NavigatorIOS> 中包含的主视图和详细视图中的 redux 状态保留了它们的原始值。

passProps 不是这样吗?

或者当数据存储状态改变时,主视图和子视图可以使用其他监听或订阅方法来更新吗?

Known issue 与 NavigatorIOS

passProps 发生变化时,NavigatorIOS 不会重新渲染场景。

通过在层次结构的较低点连接 redux 来绕过

您可以通过将组件 MasterMenu 与 redux 而非 MainView 连接来绕过此问题。

@purii 的建议解决了我的问题

我为加载到 NavigatorIOS 组件中的 "Master View" 组件创建了一个包装器。

我还为从 "Master View" 组件向下钻取的所有 "Child View" 组件创建了包装器。这看起来很丑陋而且是错误的,但它确实有效。使用 NavigatorIOS passProps 似乎会破坏 redux 更新。

var React = require('react-native');
var {
  Component,
} = React;


import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';

import * as appActions from '../actions/appActions';

var MasterListView = require('../../MasterListView');

class MasterListWrapper extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log('****** PlanList::render ****');
    return (
      <MasterListView {...this.props} />
    );
  }
}

// mapStoreStateToComponentProps would be a more descriptive name for mapStateToProps
function mapStateToProps(state) {
  return {
    state: state.appState,
  };
}
function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(Object.assign({}, appActions), dispatch),
  }
}
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(MasterListWrapper)

然后我将 MasterListWrapper 作为 NavigatorIOS 组件传递:

<Icon.TabBarItem
style={{borderColor:'red', borderWidth:0}}
title="Plan"
iconName="list"
selected={this.state.selectedTab === 'planTab'}
onPress={() => {
  this.setState({
    selectedTab: 'planTab',
    presses: this.state.presses + 1
  });
}}>
<View style={ss.container}>
<NavigatorIOS
ref="nav"
style={ss.container}
initialRoute={{
  title: 'Field Planner',
  component: MasterListWrapper,
  passProps: {
  },
}}
/>
</View>

</Icon.TabBarItem>

MasterListView 我需要添加 componentWillReceiveProps 来让我的 ListView 重新-当 redux 状态改变时渲染。

  componentWillReceiveProps: function(nextProps) {
    this.setState({
      // Force all rows to render
      dataSource: ds.cloneWithRows(nextProps.state.waypointItemList),
    });
  },

这可能不是最好的方法。我将寻找更好的方法。

然而,在我的 javascript 和 react-native 学习曲线的这一点上,我很高兴它起作用了。

Redux 非常酷。我有多个标签。我可以转到菜单并更改设置,例如,将单位从英尺更改为米,然后我的所有视图都会重新呈现。