Redux& NavigatorIOS不会在react-native中更新子视图中的状态?

时间:2016-03-05 17:12:12

标签: react-native redux navigator

如何在NavigatorIOS中包含redux更新主视图和详细信息视图?

主视图和详细视图都不会更新:

MainView> TabBar> TabBarItem> NavigatorIOS> MasterMenu>细节

其他TabBarItem使用redux工作得很好。例如:

MainView> TabBar TabBarItem>自拍

  <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&gt; TabBar&gt; TabBarItem&gt; NavigatorIOS&gt; MasterMenu&gt;细节执行 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&gt;的 MainView 的方式。 MasterMenu&gt;细节

文件: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-&gt; DetailMenu视图的NavigatorIOS,在详细信息视图中调用操作,状态更改以及TabBarIOS更新中的所有其他视图。但是,<NavigatorIOS>中包含的主视图和详细视图中的redux状态保留其原始值。

passProps不是这样做的吗?

或者是否存在主数据库和子视图可用于在数据存储状态更改时更新的其他侦听或订阅方法?

2 个答案:

答案 0 :(得分:1)

带有NavigatorIOS的

Known issue

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

通过在层次结构中的较低点连接redux来旁路

您可以通过将组件MasterMenu与redux而不是MainView相关联来绕过此问题。

答案 1 :(得分:0)

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

我为&#34; Master View&#34;创建了一个包装器。组件加载到NavigatorIOS组件中。

我还为所有&#34; Child View&#34;创建了包装器。从&#34;主视图&#34;中钻取的组件零件。这似乎是丑陋和错误的,但它的确有效。使用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 ,以便在redux状态发生变化时重新渲染 ListView

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

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

然而,在我的javascript和本地反应学习曲线的这一点上,我很高兴它有效。

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