Kotlin/React组件不更新:井字棋移植后界面未同步
Kotlin/JS React井字棋:状态更新后组件不刷新的解决办法
问题根源
- 直接修改可变列表无法触发重渲染:
useState对于引用类型(比如MutableList),只有当引用本身发生变化时才会触发组件更新。你直接修改squares[it.i] = "X"只是改变了列表内部元素的值,列表的引用并未改变,因此Board组件不会重新渲染,Square的文本自然不会同步更新。 - 子组件定义在父组件内部:
MySquare被定义在Board组件内部,每次Board渲染时都会重新创建这个函数组件,既没必要还可能引发额外的渲染异常。
修改后的代码
external interface SquareProps: Props { var value: String var theHandleClick: () -> Unit } val Square: FC<SquareProps> = FC<SquareProps> { props -> button { +"${props.value}" className = ClassName("square") onClick = { props.theHandleClick() } } } external interface MySquareProps: Props { var squareValue: String var onSquareClick: () -> Unit } // 将MySquare移到Board外部,避免重复创建 val MySquare: FC<MySquareProps> = FC<MySquareProps> { props -> Square { value = props.squareValue theHandleClick = props.onSquareClick } } val Board: FC<Props> = FC<Props> { val status: String = "Next player: X" // 改用不可变List,状态更新时通过创建新列表触发重渲染 var squares: List<String> by useState(List(9) { "" }) div { div { className = ClassName("status") +status } div { className = ClassName("board-row") MySquare { squareValue = squares[0] onSquareClick = { // 创建新列表并修改对应位置,重新赋值触发状态更新 val newSquares = squares.toMutableList() newSquares[0] = "X" squares = newSquares } } // 其他格子按此逻辑类推 } // 其他行代码 } }
关键修改说明
- 使用不可变List:将状态定义为不可变
List,更新时创建新的列表实例,确保引用变化触发组件重渲染。 - 分离子组件定义:把
MySquare移到Board外部,避免每次父组件渲染都重新生成子组件。 - 明确状态传递:通过
MySquareProps传递具体的squareValue和点击事件,让子组件只负责展示和触发回调,状态修改逻辑统一放在父组件中。
内容的提问来源于stack exchange,提问作者LinuxMintRocks
相关产品推荐
相关产品推荐

