参考QF.UIWidgets

参考Unity官方示例 - ConnectAppCN

前面说过,当时没想明白一个问题,在reducer中每次返回一个new State(), 会造成极大浪费,没想到用什么办法来解决。

然后发现这些示例里面并没有每次创建一个新的State,只是直接修改了相应的值……那这样就简单多了。把Redux结构划分为不同数据模块,更方面管理。

在这里从头做一个简单的demo,包含两个页面:“homepage”,显示一条信息, “newpage”,显示一个计数

入口

// Main.cs
using System.Collections.Generic;
using Unity.UIWidgets;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.material;
using Unity.UIWidgets.Redux;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Redux.State;
using Redux.Reducer;
using Redux.View; namespace Redux
{
public class Main : UIWidgetsPanel
{
protected override void OnEnable()
{
base.OnEnable();
} protected override Widget createWidget()
{
var widget = new MaterialApp(
initialRoute: "/",
routes: new Dictionary<string, WidgetBuilder>()
{
{ "/", context => new HomePage() },
{ "new", context => new NewPage() },
}
); var store = new Store<AppState>(
reducer: AppReducer.Reduce,
initialState: new AppState()
); return new StoreProvider<AppState>(
child: widget,
store: store
);
}
}
}

View部分

// View/HomePage.cs
// 因为这里不是重点,NewPage略
using System;
using System.Collections.Generic;
using Unity.UIWidgets.materal;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.Redux;
using Unity.UIWidgets.widgets;
using UnityEngine; namespace Redux.View
{
public class HomePage : StatelessWidget
{
var widget = new Scaffold(
appBar: new appBar(
title: new Text("Home")
),
body: new Center(
children: new List<Widget>
{
new StoreConnector<AppState, string>(
converter: (state) => state.globalState.message,
builder: (context1, text, dispatcher) => new Text(text)
),
new StoreConnector<AppState, object>(
converter: (state) => null,
builder: (context2, _, dispatcher) => new RaisedButton(
child: new Text("当前时间"),
onPressed: () => {
dispatcher.dispatch(new Action.Global.SetMessageAction
{
message = DateTime.Now.ToString()
});
}
)
),
new RaisedButton(
child: new Text("打开新页面"),
onPressed: () => {
Navigator.pushNamed(context, "new");
}
)
}
)
); return widget;
}
}

State部分


// State/AppState.cs
namespace Redux.State
{
public class AppState
{
public BagState bagState;
public GlobalState globalState; public static AppState GetState()
{
AppState = new AppState
{
bagState = new BagState
{
itemCount = 0;
},
globalState = new GlobalState
{
message = "hello",
},
}
}
}
} // State/BagState.cs
namespace Redux.State
{
public class BagState
{
public int itemCount;
}
} // State/GlobalState.cs
namespace Redux.State
{
public class GlobalState
{
public string message;
}
}

Action部分

// Action/BagAction.cs
namespace Redux.Action
{
public interface IBagAction {}
} namespace Redux.Action.Bag
{
public class AddCountAction : IBagAction
{
public int count;
} public class RemoveCountAction : IBagAction
{
public int count;
}
} // Action/GlobalAction.cs
namespace Redux.Action
{
public interface IGlobalAction {}
} namespace Redux.Action.Global
{
public class SetMessageAction : IGlobalAction
{
public string message;
}
}

Reducer部分


// Reducer/AppReducer.cs
using Redux.Action;
using Redux.State; namespace Redux.Reducer
{
public static class AppReducer
{
public static AppState Reduce(AppState state, object action)
{
switch (action)
{
case IBagAction bagAction:
return BagReducer.Reduce(state, bagAction);
case IGlobalAction globalAction:
return GlobalReducer.Reduce(state, globalAction);
default:
return state;
}
}
}
} // Reducer/BagReducer.cs
using Redux.Action;
using Redux.Action.Bag;
using Redux.State; namespace Redux.Reducer
{
public static class BagReducer
{
public static AppState Reduce(AppState state, IBagAction action)
{
switch (action)
{
case AddCountAction addCountAction:
return OnAddCountAction(state, addCountAction);
case RemoveCountAction removeCountAction:
return OnRemoveCountAction(state, removeCountAction);
default:
return state;
}
} private static AppState OnAddCountAction(AppState state, AddCountAction action)
{
state.bagState.itemCount += action.count;
return state;
} private static AppState OnRemoveCountAction(AppState state, RemoveCountAction action)
{
state.bagState.itemCount -= action.count;
return state;
}
}
} // Reducer/GlobalReducer.cs
using Redux.Action;
using Redux.Action.Global;
using Redux.State; namespace Redux.Reducer
{
public static class GlobalReducer
{
public static AppState Reduce(AppState state, IGlobalAction action)
{
switch (action)
{
case SetMessageAction setMessageAction:
return OnSetMessageAction(state, setMessageAction);
default:
return state;
}
} private static AppState OnSetMessageAction(AppState state, SetMessageAction action)
{
state.globalState.message = action.message;
return state;
}
}
}

按这样的模式,redux部分(仅此部分)可以考虑写相应的代码生成工具了

Unity - UIWidgets 7. Redux接入(二) 把Redux划分为不同数据模块的更多相关文章

  1. redux源码解析-redux的架构

    redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且r ...

  2. 关于 Unity WebGL 的探索(二)

    关于 Unity WebGL 的探索(二) 上一篇博客记录了关于 WebGL 移植的第一步:部分 C/C++ 插件的编译,目前项目中的部分插件使用该方法通过,接下来比较大的一部分工作量是网络模块 We ...

  3. react第十六单元(redux的认识,redux相关api的掌握)

    第十六单元(redux的认识,redux相关api的掌握) #课程目标 掌握组件化框架实现组件之间传参的几种方式,并了解两个没有任何关系组件之间通信的通点 了解为了解决上述通点诞生的flux架构 了解 ...

  4. react+redux教程(二)redux的单一状态树完全替代了react的状态机?

    上篇react+redux教程,我们讲解了官方计数器的代码实现,react+redux教程(一).我们发现我们没有用到react组件本身的state,而是通过props来导入数据和操作的. 我们知道r ...

  5. 动手实现 Redux(二):抽离 store 和监控数据变化

    上一节 的我们有了 appState 和 dispatch: let appState = { title: { text: 'React.js 小书', color: 'red', }, conte ...

  6. 二刷Redux笔记

    关于react的一些思考 所有的数据全部先要发送给容器,然后容器负责接受数据单后再分发数据给他下面的组件,通过props来传递,一个页面就可以相当于一个容器,容器之中就会有很多子组件,一般组件只负责接 ...

  7. [Redux + Webpack] Hot reloading Redux Reducers with Webpack

    Webpack will hot reload the component, but the reducer we need hard refresh. To sovle the problem, g ...

  8. [Unity+Android]横版扫描二维码

    原地址:http://blog.csdn.net/dingxiaowei2013/article/details/25086835 终于解决了一个忧伤好久的问题,严重拖了项目进度,深感惭愧!一直被一系 ...

  9. Unity Shader 知识点总结(二)

    紧接着上一篇文章的shader入门知识的总结,本文主要总结shader中的纹理贴图.透明度混合.顶点动画.后期特效处理等操作.如果有什么地方有错,请指出更正,谢谢.本文的代码主要来自开源书:unity ...

  10. Redux学习笔记:Redux简易开发步骤

    该文章不介绍Redux基础,也不解释各种乱乱的概念,网上一搜一大堆.只讲使用Redux开发一个功能的步骤,希望可以类我的小白们,拜托它众多概念的毒害,大牛请绕道! 本文实例源代码参考:React-Re ...

随机推荐

  1. Go 并发模型—Goroutines

    前言 Goroutines 是 Go 语言主要的并发原语.它看起来非常像线程,但是相比于线程它的创建和管理成本很低.Go 在运行时将 goroutine 有效地调度到真实的线程上,以避免浪费资源,因此 ...

  2. Geo

    Geo 应用情景 打车时寻找半径在多少范围的司机 查找附近的酒店,微信摇一摇 Linux中文乱码如何处理? redis-cli --raw docker: docker exec -it redis ...

  3. Word书签替换,加盖电子印章及转换PDF(Java实用版)

    一.前言 在项目中有需要对word进行操作的,可以看看哈,本次使用比较强大的spire组件来对word进行操作,免费版支持三页哦,对于不止三页的word文件,可以购买收费版,官网:https://ww ...

  4. Linux下定时清空某个文件

    问题 在一台单点机器部署完成且运行一段时间后,发现页面接口报错,登上机器发现磁盘满了.通过du -lh --max-depth=1 和 du -sh * 找出是哪个文件. 发现是 项目中 stdout ...

  5. P1880 [NOI1995] 石子合并 题解

    区间DP. 首先将其复制一遍(因为是环),也就是经典的破环成链. 设 \(f[i][j]\) 表示将 \(i\) 到 \(j\) 段的石子合并需要的次数. 有 \[f[i][j] = 0(i = j) ...

  6. python命令行解析模块argparse

    argparse是Python标准库中推荐的命令行解析模块 code01: tmp.py import argparse parser = argparse.ArgumentParser(descri ...

  7. SpringBoot3之Web编程

    标签:Rest.拦截器.swagger.测试; 一.简介 基于web包的依赖,SpringBoot可以快速启动一个web容器,简化项目的开发: 在web开发中又涉及如下几个功能点: 拦截器:可以让接口 ...

  8. 《小白WEB安全入门》02. 开发篇

    @ 目录 初识HTML潜在漏洞 初识CSS潜在漏洞 初识JS潜在漏洞 初识后端潜在漏洞 后端能做什么 后端种类 后端框架 潜在漏洞 本系列文章只叙述一些超级基础理论知识,极少有实践部分 本文涉及到的语 ...

  9. api接口对接如何实现,php如何对接api

    API接口对接是现代软件开发中不可或缺的一部分,它允许不同的应用程序之间进行数据交换和服务调用.在PHP中,可以使用多种方式实现API接口的对接,包括基于HTTP协议的传统方法以及现代的API客户端库 ...

  10. from itertools import groupby

    需求:期望由 a 得到 b 实现方法: from itertools import groupby a = [ {'name': 'a', 'value': 1}, {'name': 'b', 'va ...