Redux在Flutter中應(yīng)用

Redux應(yīng)用

概述

Flutter 是 Google 開(kāi)源的 跨平臺(tái)開(kāi)發(fā)工具,我們可以在anroid,iOS上完成功能開(kāi)發(fā),避免兩撥人力成本。

Redux對(duì)于JavaScript應(yīng)用而言是一個(gè)可預(yù)測(cè)狀態(tài)的容器。換言之,它是一個(gè)應(yīng)用數(shù)據(jù)流框架,而不是傳統(tǒng)的像underscore.js或者AngularJs那樣的庫(kù)或者框架。后來(lái)在Rn和Flutter上都開(kāi)發(fā)了,今天給大家分享一下在Flutter中使用Redux。

一、集成Redux

在項(xiàng)目的pubspec.yaml的dependencies中添加:


dependencies:

...

redux: 4.0.0

flutter_redux: ^0.6.0

二、安裝

當(dāng)我們編輯了pubspec.yaml文件,AndroidStudio的編輯區(qū)域右上角會(huì)顯示put get樣式,直接點(diǎn)擊就可安裝。

你也可以在項(xiàng)目的更目錄執(zhí)行:flutter pub get

pub 官網(wǎng)有詳細(xì)介紹安裝步驟:https://pub.dev/packages/scoped_model#-installing-tab-

三、Redux使用

  • 定義model

  • 定義State

  • 定義Action,操作類(lèi)型,比如添加書(shū)、刪除書(shū)等不同類(lèi)型的標(biāo)識(shí)。

  • 定義Reducer(定義了應(yīng)用如何響應(yīng)Redux發(fā)出Action,即發(fā)出的Action由誰(shuí)處理)

  • 創(chuàng)建Store,負(fù)責(zé)綁定Reducer和默認(rèn)數(shù)據(jù)。

  • 使用Redux在Flutter中提供的Widget創(chuàng)建視圖,并和Store綁定。

  • 發(fā)送通過(guò)Store的dispatch發(fā)送Action。

我們通過(guò)一個(gè)添加書(shū)籍列表來(lái)完成Redux的使用,運(yùn)行效果圖:


booklist_redux.gif

1、定義model,我們創(chuàng)建一個(gè)book.dart,代碼如下:


/// 定義book 類(lèi)型

class Book {

String name;

int id;

Book({this.name, this.id});

}

2、定義state,創(chuàng)建一個(gè)book_state.dart文件,代碼如下:


/// 持有一個(gè)類(lèi)型是book的list對(duì)象

class BookListState{

List books;  BookListState({this.books});}

3、定義Action,分別定義一個(gè)添加和刪除的Action。并定義刪除書(shū)和添加書(shū)的邏輯處理方法,創(chuàng)建book_action.dart類(lèi),代碼如下:


import 'package:booklist/book/bean/book.dart';

/// 添加book的Action

class AddBootAction {

Book book;

AddBootAction({this.book});

}

/// 刪除book的Action

class DeleteBootAction {

DeleteBootAction();

}

/// 添加書(shū)籍的方法

/// 注意這里的返回值一定是和我們?cè)贐ookState中定義的狀態(tài)類(lèi)型一樣。

/// 方法參數(shù) books,這個(gè)參數(shù)就是我們?cè)赟tate定義的變量books,Redux發(fā)送消息時(shí),攜帶過(guò)來(lái)。

/// action就是對(duì)應(yīng)的我們上面定義的AddBootAction,二者如何管理,我們?cè)诘谒牟街写_認(rèn)

List addBook(List books, action) {

// 將書(shū)籍添加到列表中。

books.add(action.book);

return books;

}

///刪除書(shū)籍的方法,這里的返回類(lèi)型和形參和上面的一樣。

List deleteBook(List books, action) {

books.removeLast();

return books;

}

4、定義Reducer,將Action和操作方法綁定,創(chuàng)建一個(gè)book_reducer.dart,代碼如下:


import 'package:redux/redux.dart';

import 'package:booklist/book/bean/book.dart';

import 'package:booklist/book/book_action/book_action.dart';

/// 通過(guò)Redux提供的combineReducers方法,將Action和操作方法綁定

/**

* 1、combineReducers是Redux提供創(chuàng)建Reducer的方法。

* 2、combineReducers泛型一定要是我們?cè)赟tate中定義的類(lèi)型。

* 3、TypedReducer是Redux提供的默認(rèn)Reducer響應(yīng)

* 4、TypedReducer的第一個(gè)泛型必須是State中定義的類(lèi)型。

* 5、TypedReducer的第一個(gè)泛型即是我們定義的Action類(lèi)型。

* 6、TypedReducer的形參就是我們?cè)赽ook_action.dart中的定義的具體操作方法。

* 7、dart語(yǔ)音中可以把方法當(dāng)作參數(shù)

* 8、這樣就把Action和方法操作綁定了。有點(diǎn)類(lèi)似EventBus哦

*/

final BookReducer = combineReducers>([

TypedReducer, AddBootAction>(_addBook),

TypedReducer, DeleteBootAction>(_deleteBook),]

);

5、創(chuàng)建Store,將Redux和綁定到Store中,Store一般定義在Widget中,同時(shí)也包含了發(fā)送Action,所以我們創(chuàng)建book_list_widget.dart(包含了5,6,7)


import 'package:booklist/book/bean/book.dart';

import 'package:booklist/book/book_action/book_action.dart';

import 'package:booklist/book/state/book_state.dart';

import 'package:flutter/cupertino.dart';

import 'package:flutter/material.dart';

import 'package:flutter_redux/flutter_redux.dart';

import 'package:redux/redux.dart';

/// 定義有狀態(tài)的widget

class BookListWidget extends StatefulWidget {

@override

State createState() => BookListState();

}

/// flutter狀態(tài)

class BookListState extends State {

// 定義Redux store,包含了Reducer 第五步

final store = new Store(

// 在book_state.dart中定義

bookReducer,

// 設(shè)置一個(gè)默認(rèn)值

initialState: BookList(books: [

Book(name: "java 1", id: 1),    ]),  );

@override  Widget build(BuildContext context) {

// 使用Redux提供的StoreProvider作為root Widget

// 很重要:第六步

return StoreProvider(

store: store,

child: MaterialApp(

home: Scaffold(

appBar: AppBar(

title: Text("Redux使用"),

backgroundColor: Colors.blue[300],          ),

body: Column(

mainAxisAlignment: MainAxisAlignment.start,

children: [

Row(

children: [

RaisedButton(

color: Colors.red[300],

child: Text("添加書(shū)籍"),

onPressed: () {

// 很重要,第七步,通過(guò)store的dispatch 發(fā)送AddbookAction

store.dispatch(AddBookAction(book:

Book(name:"java ${store.state.books.length + 1}",

id: store.state.books.length+1)

));},),

RaisedButton(

color: Colors.red[300],

child: Text("刪除最后一本書(shū)"),

onPressed: () {

// 很重要,第七步,通過(guò)store的dispatch 發(fā)送DeletebookAction

store.dispatch(DeleteBookAction());},),],),

Expanded(

// 很重要,第六步

child: StoreConnector(

converter: (store) => store.state,

builder: (BuildContext context, data) {

return Container(

height: 200,

child: ListView.builder(

itemCount:

data.books.length ,

itemBuilder: (BuildContext context, position) {

return Padding(

padding: EdgeInsets.all(10.0),

child: Row(

children: [

Text(getName(data, position)),

],

),

);

}),); },), )],),),),);  }

String getName(BookList bookList, int position) {

return bookList.books[position].name;  }

}

四、結(jié)束語(yǔ)

Redux的思路和使用方法同Eventbus類(lèi)似,只是他兩解決的問(wèn)題領(lǐng)域不同步,EventBus重點(diǎn)是解決跨線(xiàn)程通信,Redux重點(diǎn)是解決狀態(tài)更新后,如何刷新UI,加入沒(méi)有Redux,如果我們的頁(yè)面有很多狀態(tài),每個(gè)都需要調(diào)用setState去更新,你想象也行代碼復(fù)雜度得多大

思考:Redux的使用有些模塊類(lèi)型的,是不是有辦法通過(guò)類(lèi)型java apt的方式自動(dòng)生成呢?

demo地址:https://github.com/choha/ReduxBookList

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容