Reputation: 4130
In my React-Native app, I had some database code that worked fine. However, I decided that I needed to shoehorn in redux to maintain certain state, especially app settings.
Once I got the redux concepts through my thick skull and implemented it, that same database code started returning promises instead of honoring the "await" statements that were previously in use.
Here is the relevant reducer and database code:
// relevant imports
export default function divisionReducer(state = {programId: 1}, action) {
switch (action.type) {
case GET_DIVISIONS_BY_PROGRAM:
// add result to state
return _.cloneDeep({...state, divisions: divisions });
default:
return state;
}
}
getAllDivisions = async (programId) => {
let db = await openDefault();
const sql = "SELECT * FROM DIVISION WHERE DIVISION_PROGRAM_ID = ?";
let sqlResult = await query(db, sql, [programId]);
await close(db);
// function to convert db snake case to camelcase
result = keysToCamelCase(sqlResult.result);
return result;
}
My question: why is this code not honoring the "await" keywords?
Edit: More Code Added by Request
Below is the divisionAction code:
import { GET_DIVISIONS_BY_PROGRAM } from "./actionTypes";
export const getAllDivisions = (programId) => {
return {
type: GET_DIVISIONS_BY_PROGRAM,
payload: programId
}
}
Below is the DivisionManagementScreen, which calls the getAllDivisions code:
port React, {Component} from "react";
import {View, FlatList, Alert} from "react-native";
import {withNavigation} from "react-navigation";
import {connect} from "react-redux";
import masterStyles, {listPage, bigButtonStyles} from "./../../styles/master";
import {getAllDivisions} from "./../../redux/actions/divisionActions";
import DivisionManagementRow from "./DivisionManagementRow";
class DivisionManagmementScreen extends Component {
constructor(props) {
super(props);
}
async componentDidMount() {
this.props.getAllDivisions(this.props.programId);
console.log("Props after getAllDivisions: " + JSON.stringify(this.props));
}
async componentWillUnmount() {
console.log("Entered componentWillUnount()");
}
_renderItem = ({item}) => (
<DivisionManagementRow divisionId={item.DIVISION_ID} divisionName={item.DIVISION_NAME}
onAddTeam={() => {this._addTeam(item.DIVISION_ID)}}
onEdit={() => {this._editDivision(item.DIVISION_ID)}}
onDelete={() => {this._btnDeleteDivision(item.DIVISION_ID)}}/>
);
render() {
console.log("In render(), props: " + JSON.stringify(this.props));
return (
<View style={masterStyles.component}>
<View style={listPage.listArea}>
<FlatList
data={this.props.divisions}
renderItem={this._renderItem}
keyExtractor={(item) => item.DIVISION_ID.toString() } />
</View>
<View style={listPage.bottomButtonArea}>
<PortableButton defaultLabel="Add Division"
disabled={false}
onPress={() => {this._addDivision()}}
onLongPress={() => {}}
style={bigButtonStyles} />
</View>
</View>
);
}
}
function mapStateToProps(state) {
return {
programId: state.divisionReducer.programId,
divisions: state.divisionReducer.divisions
};
}
export default withNavigation(connect(mapStateToProps, {getAllDivisions})(DivisionManagmementScreen));
Is this enough code to diagnose?
Upvotes: 0
Views: 584
Reputation: 4130
So, instead of writing my database-enabled action creator correctly (starting with " return (dispatch) => { /* blah blah blah */ } ), I was still having it return an object, and having the reducer call the method with the database code.
I finally got the concepts through my thick skull, and got the code working over a weekend.
Upvotes: 0
Reputation: 12437
I can't see where you're actually calling your getAllDivisions
async function. I can only see you trying to call the getAllDivisions
action creator - action creators just emit actions syncronously, by default they can't call functions with side effects.
If you want to trigger side effects, like your DB async function you need to look into a library like redux-thunk. Or more advanced would be redux-saga. If you're new to this stuff, I advise starting with redux-thunk.
Also I think the way you're using the connect()
function is wrong. The second argument mapDispatchToProps
needs to actually dispatch your actions to the store. So it should look like this:
function mapStateToProps(state) {
return {
programId: state.divisionReducer.programId,
divisions: state.divisionReducer.divisions
};
}
function mapDispatchToProps(dispatch) {
return {
getAllDivisions () {
dispatch(getAllDivisions())
}
};
}
export default withNavigation(
connect(
mapStateToProps, mapDispatchToProps
)(DivisionManagmementScreen)
)
Upvotes: 1