Sas*_*asa 4 dart flutter riverpod
我正在使用StateProvider<List<String>>来跟踪井字游戏板上的用户点击。实际板是一个扩展ConsumerWidget 的小部件,由可点击的 GridView 组成。
在GridViews 子级的onTap事件中,调用以下命令来更新状态:
ref.read(gameBoardStateProvider.notifier).state[index] = 'X';
Run Code Online (Sandbox Code Playgroud)
由于某种原因,这不会调用小部件重建事件。因此,我看不到被点击的 GridView 项目中的“X”。
但是,如果我添加额外的“简单”StateProvider<int> 并在同一 onTap 事件中调用它,那么小部件将被重建,并且我可以在 GridView 中看到“X”。我什至没有使用或显示这个附加的状态提供程序,但由于某种原因它会调用重建,而我想要的提供程序却不会。
final gameBoardStateProvider = StateProvider<List<String>>((ref) => List.filled(9, '', growable: false));
final testStateProvider = StateProvider<int>((ref) => 0); //dummy state provider
class Board extends ConsumerWidget {
const Board({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final gameBoard = ref.watch(gameBoardStateProvider);
final testState = ref.watch(testStateProvider);
return Expanded(
child: Center(
child: GridView.builder(
itemCount: 9,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
shrinkWrap: true,
itemBuilder: ((BuildContext context, int index) {
return InkWell(
onTap: () {
//With this line only the widget does not get refreshed - and I do not see board refreshed with added 'X'
ref.read(gameBoardStateProvider.notifier).state[index] = 'X';
//??? If I add this line as well - for some reason the widget get refreshed - and I see board refreshed with added 'X'
ref.read(testStateProvider.notifier).state++;
},
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.white)),
child: Center(
child: Text(gameBoard[index]),
),
),
);
}),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
一旦你这样做了
ref.read(gameBoardStateProvider.notifier).state[index] = 'X'
Run Code Online (Sandbox Code Playgroud)
意味着改变单个变量。为了更新 UI,您需要提供一个新列表作为 State。
你可以这样做
List<String> oldState = ref.read(gameBoardStateProvider);
oldState[index] = "X";
ref
.read(gameBoardStateProvider.notifier)
.update((state) => oldState.toList());
Run Code Online (Sandbox Code Playgroud)
或者
List<String> oldState = ref.read(gameBoardStateProvider);
oldState[index] = "X";
ref.read(gameBoardStateProvider.notifier).state =
oldState.toList();
Run Code Online (Sandbox Code Playgroud)
为什么testStateProvider有效:
因为它包含单个 int 作为 State,其中gameBoardStateProvider包含List<String>作为 State。
仅更新单个变量不会刷新 ui
state_provider,需要更新状态来强制刷新
更多关于state_provider
您还可以检查change_notifier_provider
| 归档时间: |
|
| 查看次数: |
6123 次 |
| 最近记录: |