Suppose I have a SnapshotStateList for Student, and the definition of Student is:
data class Student<val id: Int, var name: String>
val students = mutableStateListOf(Student(0, "Aaron"))
My Jetpack compose in wants to recompose when students changes.
Found the following function to trigger it:
fun addStudent(name: String) {
students.add(Student(students.size, "Bob"))
}
fun removeStudent(key: Int) {
students.remove(key)
}
fun replaceStudent(key: Int, name: String) {
val old = students[key]
students[key] = Student(old.key, name)
}
But the following function cannot trigger it:
fun modifyStudent(key: Int, name: String) {
students[key].name = name
}
Why, how does SnapshotStateList detect that a change has occurred?
The snapshot system will detect changes in SnapshotStateList
itself, not in changes to mutable state within it.
The code,
fun replaceStudent(key: Int, name: String) {
val old = students[key]
students[key] = Student(old.key, name)
}
modifies students
and is detected as a change.
fun modifyStudent(key: Int, name: String) {
students[key].name = name
}
modifies the name
property of some Student
object which is not seen by the snapshot system as a change.
I recommend you make Student
immutable instead of mutable,
data class Student(val id: Int, val name: String)
Then replaceStudent
would be required to modify update the student.
You could, alternately, change Student
to,
class Student(val id: Int, name: String) {
var name by mutableStateOf(name);
}
which will make Student
observable and notify Compose whenever the name
property is changed.
I recommend making Student
immutable.
As a bonus, I recommend you use SnapshotStateMap
instead of SnapshotStateList
in this case as if you ever call removeStudent
above the key
of the students after the remove will not match the index into the students
. Using a SnapshotStateMap
will fix this. You also need to change the addStudent
to not use size
as the next id
but, rather, use a global integer or an global atomic (if you are multi-threaded) as, now, creating a new student will overwrite an existing student's data as it causes duplicate key
values to be generated if any student was deleted.