Android ステートフルとステートレスってなに?
Googleの公式リファレンスにも出てくるステートフルとステートレスを簡単なコードとともにわかりやすく解説しています。
ステートフルとは
プログラムやシステムが状態(ステート)を持ち、その状態に基づいて振る舞いや処理を行うことを意味します。
Googleの公式文章にあるコード例にした場合、HelloConten()関数の4行目で変数nameを宣言しています。
5行目ではnameの値が空かどうかで処理を分けており、14行目ではnameに値を代入しています。
よってHelloContent()関数は状態(name)を保ち、その状態に基づいて振る舞いや処理を行っているためステートフルといえます。
@Composable
fun HelloContent() {
Column(modifier = Modifier.padding(16.dp)) {
var name by remember { mutableStateOf("") }
if (name.isNotEmpty()) {
Text(
text = "Hello, $name!",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
}
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Name") }
)
}
}
ステートレスとは
ステートフルの逆で内部で状態を一切持たないことを指します。
Googleの公式文章にあるコード例にした場合、HelloScreen()の3行目で変数nameを宣言し、それとラムダ式をHelloContent()関数に渡しています。
これによりHelloContent()関数では変数の宣言が不要です。
また、関数型パラメータonNameChangeを使いnameの値を変更しています。
このように呼び出し元に状態を持たせてステートレスにするプログラミングパターンを状態ホイスティングと呼びます。
状態ホイスティングについてはこちら。
@Composable
fun HelloScreen() {
var name by rememberSaveable { mutableStateOf("") }
HelloContent(name = name, onNameChange = { name = it })
}
@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "Hello, $name",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
OutlinedTextField(
value = name,
onValueChange = onNameChange,
label = { Text("Name") }
)
}
}