我一直在努力将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>
);
}
}