Skip to content

Instantly share code, notes, and snippets.

@zach-klippenstein
Last active October 20, 2022 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zach-klippenstein/ed184c7c7ad9b21cd9fd8c3a49e4a584 to your computer and use it in GitHub Desktop.
Save zach-klippenstein/ed184c7c7ad9b21cd9fd8c3a49e4a584 to your computer and use it in GitHub Desktop.
Code for twitter thread about why onClick handlers don't let you emit composables. https://twitter.com/zachklipp/status/1583165356322930688
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@Composable
fun CursedButtonDemo() {
var counter by remember { mutableStateOf(0) }
Column(modifier = Modifier.wrapContentSize()) {
Text("Counter: $counter")
CursedButton(
onClick = {
counter++
{
CursedButton(
onClick = {
counter++
{
Text("STOP CLICKING!!")
}
},
) {
Text("Thanks for humoring me")
}
}
}
) {
Text("Click me!")
}
}
}
@Composable
fun CursedButtonDemo2() {
var counter by remember { mutableStateOf(0) }
Column(modifier = Modifier.wrapContentSize()) {
Text("Counter: $counter")
CursedButton2(
onClick = {
LaunchedEffect(Unit) {
counter++
}
CursedButton2(
onClick = {
LaunchedEffect(Unit) {
counter++
}
Text("STOP CLICKING!!")
},
) {
Text("Thanks for humoring me")
}
}
) {
Text("Click me!")
}
}
}
@Composable
fun BlessedButtonDemo() {
var counter by remember { mutableStateOf(0) }
Column(modifier = Modifier.wrapContentSize()) {
Text("Counter: $counter")
when (counter) {
0 -> Button(onClick = { counter++ }) {
Text("Click me!")
}
1 -> Button(onClick = { counter++ }) {
Text("Thanks for humoring me")
}
else -> Text("STOP CLICKING!!")
}
}
}
@Composable
fun CursedButton(
onClick: () -> @Composable () -> Unit,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
val (actualContent, updateContent) = remember {
mutableStateOf<(@Composable () -> Unit)?>(null)
}
if (actualContent != null) {
Box(modifier = modifier, propagateMinConstraints = true) {
actualContent()
}
} else {
Button(
onClick = { updateContent(onClick()) },
modifier = modifier
) {
content()
}
}
}
@Composable
fun CursedButton2(
onClick: @Composable () -> Unit,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
val (actualContent, updateContent) = remember {
mutableStateOf<(@Composable () -> Unit)?>(null)
}
if (actualContent != null) {
Box(modifier = modifier, propagateMinConstraints = true) {
actualContent()
}
} else {
Button(
onClick = { updateContent(onClick) },
modifier = modifier
) {
content()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment