容器/组件在状态更改后未更新

时间:2016-02-19 14:31:41

标签: javascript ios reactjs react-native redux

我一直在努力将Redux集成到我的React Native应用程序中。我被困在获取异步数据库fetch以更新必要的组件。

我可以看到数据库调用正在获取数据,并且它正确返回状态(使用redux-logger检查)。但是,我对isFetching为假的检查从未在容器中进行评估。我认为我已经宣布mapStateToProps方法没有触发更新。

我已经检查过我在减速机中没有改变状态!

更新

这似乎是我遗漏的看似微不足道的部分,最终成为问题的根源。我现在看到NavigatorIOS就是问题所在。通过passProps传入的任何道具都不会随州一起更新。这似乎是一个众所周知的问题:https://github.com/facebook/react-native/issues/795

行动:

export function fetchItems() {
  return function(dispatch) {
    dispatch({ type: 'REQUEST_ITEMS' })


    AsyncDatabaseCall()  
    .then((res) => {
      // console.log (res.rows)
      dispatch({ type: 'RECEIVE_ITEMS_SUCCESS', data: res })
      // *** Execution reaches here ***
    })
    .catch((err) => {
      console.log(err)
      dispatch({ type: 'RECEIVE_ITEMS_FAILURE', error: err })
    })

减速器:

var initialState = {
  isFetching: true,
  rows: []
}

export default function items(state = initialState, action = {}) {
  switch (action.type) {
    case 'REQUEST_ITEMS':
      return Object.assign({}, state, { 
        isFetching: true 
      });
    case 'RECEIVE_ITEMS_SUCCESS':
      // *** Execution reaches here ***
      return Object.assign({}, state, { 
        isFetching: false,
        rows: action.data.rows,
        lastUpdated: action.receivedAt
      });
    case 'RECEIVE_ITEMS_FAILURE':
      return Object.assign({}, state, { 
        isFetching: false, 
        error: action.error 
      });

    default:
      return state
  }
}

容器:

class ItemIndex extends Component {

  constructor(props) {
    super(props);
  }

  componentWillMount() {
    console.log ("isFetching")
    console.log (this.props.items.isFetching)
  }

  render() {
    if (this.props.items.isFetching) {
      //render loading screen
      console.log ("will be loading...")
      return (
        <View/>
      )
    } else {
      console.log ("got the data") // execution never reaches here
      return (
        <Items {...this.props} />
      )
    }
  }
};

module.exports = ScaleIndex;

使用connect方法的容器:

class MyApp extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <MainContainer {...this.props} />
    );
  }
}

const mapStateToProps = (state) => {
  const { item, items } = state
  return {
    item,
    items,
    isFetching: items.isFetching
  }
}

const mapDispatchToProps = (dispatch) => {
  return { actions: bindActionCreators({ ...DatabaseActions, ...ItemActions }, dispatch) }
}

export default connect(mapStateToProps, mapDispatchToProps)(MyApp)

MainComponent 容器,它将 ItemIndex 作为其initialRoute

class MainComponent extends Component {
  constructor(props) {
    super(props)
  }

  render() {
    const { actions, item, items, dispatch } = this.props
    console.log ("MainComponent items")
    console.log (items) // <-- this gets updated on state change
    return (
      <NavigatorIOS
        ref = "nav"
        style = {styles.navigator}
        initialRoute = {{
          passProps: { actions: actions, item: item, items: items, dispatch: dispatch },
          title: 'Items',
          component: ItemIndex
        }}
        /> 
    )
  }
}

..最后是根容器

export default class App extends Component {
  constructor (props) {
    super (props)
    // Load all items first.
    store.dispatch(fetchItems())
  }

  render() {
    console.log ("store.getState:")
    console.log (store.getState())
    return (
      <Provider store={store}>
        <MyApp />
      </Provider>
    );
  }
}

0 个答案:

没有答案