-2
I have a class component where I run a callback (filterTasks) right after a status change (toggleFilter), all normal and trouble-free.
export default class TaskList extends Component {
state = {
showDoneTasks: true,
showAddTask: false,
visibleTasks: [],
tasks: [{
id: Math.random(),
desc: 'Comprar Livro de React Native',
estimateAt: new Date(),
doneAt: new Date()
}, {
id: Math.random(),
desc: 'Ler Livro de React Native',
estimateAt: new Date(),
doneAt: null
}]
}
toggleTask = taskId => {
const tasks = [...this.state.tasks]
tasks.forEach(task => {
if (task.id === taskId) {
task.doneAt = task.doneAt ? null : new Date()
}
})
this.setState({ tasks }, this.filterTasks)
}
componentDidMount = () => {
this.filterTasks()
}
toggleFilter = () => {
this.setState({ showDoneTasks: !this.state.showDoneTasks }, this.filterTasks)
}
filterTasks = () => {
let visibleTasks = null
if (this.state.showDoneTasks) {
visibleTasks = [...this.state.tasks]
} else {
const pending = task => task.doneAt === null
visibleTasks = this.state.tasks.filter(pending)
}
this.setState({ visibleTasks })
}
render() {
const today = moment().locale('pt-br').format('ddd, D [de] MMMM')
return (
<View style={styles.container}>
<AddTask
isVisible={this.state.showAddTask}
onCancel={() => this.setState({ showAddTask: false })}
/>
<ImageBackground source={todayImage} style={styles.background}>
<View style={styles.iconBar}>
<TouchableOpacity onPress={this.toggleFilter}>
<Icon
name={this.state.showDoneTasks ? 'eye' : 'eye-slash'}
size={20}
color={commonStyles.colors.secondary} />
</TouchableOpacity>
</View>
<View style={styles.titleBar}>
<Text style={styles.title}>Hoje</Text>
<Text style={styles.subtitle}>{today}</Text>
</View>
</ImageBackground>
<View style={styles.taskList}>
<FlatList
data={this.state.visibleTasks}
keyExtractor={item => item.id}
renderItem={({ item }) =>
<Task {...item} toggleTask={this.toggleTask} />
}
/>
</View>
<TouchableOpacity
style={styles.addButton}
activeOpacity={0.7}
onPress={() => this.setState({ showAddTask: true })}
>
<Icon name='plus' size={20} color={commonStyles.colors.secondary} />
</TouchableOpacity>
</View>
)
}
}
The "strange" is that for test effect, I entered the toggleFilter method and instead of putting the filterTasks method as the second parameter of setState, I put its direct invocation, just after setState, as below:
toggleFilter = () => {
this.setState({ showDoneTasks: !this.state.showDoneTasks })
this.filterTasks()
}
In theory it was supposed to work normally, but in practice IN THE FIRST TIME toggleFilter is called is as if the line "this.setState({ showDoneTasks: !this.state.showDoneTasks })" did not work, as the attribute showDoneTasks remains true. Only the second time the attribute is changed.
Does anyone know why this difference in behavior?
Thank you for your attention