I have a problem while incorporating the redux saga in my application . What I understand from the tutorials is that the middleware will parse the action dispatched from the app and will process some async operations(asycn storage, api).
Then put another action in the pipeline which will trigget the reducer and then updates the state.
Flow is that my component button click triggers an action dispatch which is caught by the watcher in the saga, and then api calls are processed then the put is done to send data to reducer to update the state.
If in my component I dispatch the action FETCH_DATA, the saga is catching that and processing the data fetch and then calling the updateprofile. This calls the reducer and processing happens.
This is what I expected. But even before hitting the saga FETCH_DATA, the call comes to the reducer and since there is no action type FETCH_DATA case to handle it will return the default state and thiscauses the app to re render. So rendering happens twice and it is causing some problem to my items in the list.
I think this is also somewhat expected as I read in some article .How to get rid of this re rendering ?
function* datafetch(action) {
let { data } = yield call(loginApi, action.payload);
yield put(updateProfile(data.profile));
}
export function* dataFetcherSaga() {
yield takeLatest('FETCH_DATA', datafetch);
}
/reducer.js
const toDoListReducer = (state, action) => {
switch (action.type) {
case "UPDATE_APPREDUX_STATE":
return {
//some processing with data and state
};
break;
case "UPDATE_PROFILE":
return {
//some processing with data and state
};
break;
default:
return state;
}
return state;
};
export default toDoListReducer;
//action
export const fetchData = currentDay => {
return {
type: 'FETCH_DATA',
currentDay: currentDay
};
};
export function updateProfile(profile) {
return { type: 'UPDATE_PROFILE', payload: authParams };
}
//component
render(){
return (
<View style={styles.viewStyle}>
<SafeAreaView>
<View style={styles.viewPadding}>
<View>
<View style={styles.toDoViewStyle}>
<TextInput
style={styles.toDoInputStyle}
placeholder="What you gonna do ?"
onChangeText={text => {
this.newTask = text;
}}
/>
<TouchableOpacity
onPress={() => {
this.props.updateTasks(
{
taskID: new Date().getTime(),
taskDay: this.currentDay, //millisecond field to get a unique value
taskValue: this.newTask,
taskCompleted: false,
taskCompletedTime: null
},
"addTask"
);
}}
>
<Image
style={styles.addImage}
source={require("../../assets/add.png")}
/>
</TouchableOpacity>
</View>
<Text>
↓ To Do Items ↓
</Text>
<SectionList
style={styles.flatListStyle}
renderItem={({ item }) => <ToDoListItem value={item} />}
renderSectionHeader={({ section: { title, data } }) => {
if (data.length > 0) {
return (
<Text
style={{
paddingTop: 5,
fontWeight: "bold",
fontStyle: "italic",
fontSize: 15,
color: title === "Completed Tasks:" ? "green" : "red",
textDecorationLine: "underline"
}}
>
{title}
</Text>
);
}
}}
stickySectionHeadersEnabled={false}
sections={[
{
title: "Completed Tasks:",
data: this.props.tasks.filter(tasks => {
return tasks.taskCompleted === true;
})
},
{
title: "InComplete Tasks:",
data: this.props.tasks.filter(tasks => {
return tasks.taskCompleted === false;
})
},
,
]}
keyExtractor={(item, index) => item + index}
/>
</View>
</View>
</SafeAreaView>
</View>
);}
//child item
class ToDoListItem extends React.Component {
constructor(props) {
super(props);
//this.state = { checked: false };
}
selectItem = () => {
let updatedObject = {
taskID: this.props.value.taskID,
taskCompleted: !this.props.value.taskCompleted,
};
this.props.done(updatedObject);
};
deleteItem = () => {
let deletedObject = {
taskID: this.props.value.taskID,
};
this.props.delete(deletedObject);
};
render() {
return (
<View style={styles.viewStyle}>
<View style={styles.checkBoxStyle}>
<CheckBox
checkedCheckBoxColor="green"
onClick={this.selectItem}
isChecked={this.props.value.taskCompleted}/>
</View>
<View style={styles.inputTextViewStyle}>
<Text
style={
this.props.value.taskCompleted
? styles.completeDone
: styles.inComplete
}>
{this.props.value.taskValue}
</Text>
{this.props.value.taskCompleted && <Text style={{ fontSize: 11, fontStyle: "italic", color: "blue" }}>{"\n"}{"Completed @ " + this.props.value.taskCompletedTime}</Text>}
</View>
<View style={styles.deleteTextStyle}>
<TouchableOpacity onPress={this.deleteItem}>
<Image
style={styles.deleteImage}
source={require('../../assets/delete.png')}
/>
</TouchableOpacity>
</View>
</View>
);
}
}