mirrorjs / mirror Goto Github PK
View Code? Open in Web Editor NEWA simple and powerful React framework with minimal API and zero boilerplate.
License: MIT License
A simple and powerful React framework with minimal API and zero boilerplate.
License: MIT License
It would be helpful to:
Publishing releases on Github makes it easy to see what the latest and previous releases are, without having to go to NPM. To do this, you'll also have to git tag
versions of Mirror.
As a project evolves, its helpful to know what has changed - especially any possible breaking changes. You might want to consider adding a CHANGELOG.md. This could be automated
with a variety of tools, such as github-changelog-generator.
If this seems like too much work, don't worry about it. But if you'd like any assistance, I'm happy to help.
mirrorx用的是rr4 ,但是没有暴露rr4的hook,请问怎么引入?
Nice Work! The api is so sweet and backended by a good design.
I wanna to have a try with mirror for its clean design and code. But, as now i am fousing at a RN project, the router picked is react-navigation
, and i don't want to change to react-router-native
. So, i think just use mirror as a state manager is more convenient to me(like jumpstate
). I have read the code. the index.js
not export state
created by mirror. and the process of create state is in render.js
, however, adding a getState
api to init state and supply to Provider of react-redux
in my current RN project is what i want.
how about this suggestion?
没在文档上有看到相关的处理方式
How would you go about using something like React Snapshot for pre-rendering applications?
Currently mirror also overrides the render method:
https://github.com/mirrorjs/mirror/blob/master/src/render.js
and so does react snapshot:
https://github.com/geelen/react-snapshot/blob/master/src/index.js
How can I specify a router basename?
With the <BrowserRouter />
component in react-router v4, there is a basename prop:
<BrowserRouter basename="/calendar" />
<Link to="/today"/> // renders <a href="/calendar/today">
Is there a way to access or use this in the component provided in mirrorx?
import mirror, {Router, render} from 'mirrorx'
render((
<Router basename="/calendar"> // no basename prop... this doesn't work
...
</Router>
), document.getElementById('foo'));
thanks! 😄
引入 videojs 依赖, 怎么使用 es2015编译(高版本 babel 会报错), mirrorx 里面配置似乎是更高版本的 babel 编译
在组件目录下单独使用
{
"presets": [
"es2015",
"stage-2",
"react"
]
}
依然无效
In the README, there's this syntax for reducers:
reducers: {
increment(state) { return state + 1 },
decrement(state) { return state - 1 }
},
I would propose to change this to
reducers: {
increment: state => state + 1,
decrement: state => state - 1
},
That way it's clear that they are methods and we can skip the return statement.
If you want to return an object you have to wrap it in ( )
什么时候出支持typescript? 写一个dts文件?
如题~
api文档关于mirror.hook((action, getState) => {})
的描述太简单了,执行一下就移除?什么原理?看源码也找不到相应地方~
就像 https://github.com/suciuvlad/redux-dialog#step-3 ,
当中的 openDialog
, closeDialog
都是 Action Creator,需要用户手动去 dispatch
的,而不由 mirror 管理
所以我需要如何把这些绑到 mirrorx.actions
上呢? 还是说我只能在 connect 里传 mapDispatchToProps
自行处理?
There should be a way to opt out of using react-router v4.
This would be especially useful for mobile. Currently, Mirror is not compatible with "react-native" due to the dependency on react-dom
. Opting into react-router-native
isn't much better, as it's not currently the most popular routing option.
As a suggestion, using dynamic imports, would make it possible to opt out of using the router.
// default to true
options.useRouter = options.useRouter || true
if (options.useRouter) {
// dynamic import (may require Webpack plugin)
import('./router')
}
I want to make some route redirect outside of component so can you export history or a push function from react-router-redux
如题,看过如下代码后,有这个疑惑,求解
//middleware.js
function warning() {
throw new Error(
'You are calling "dispatch" or "getState" without applying mirrorMiddleware! ' +
'Please create your store with mirrorMiddleware first!'
)
}
export let dispatch = warning
// router.js
import {dispatch} from './middleware'
import {actions} from './actions'
let history
export default function Router({history = getHistory(), children}) {
// Add `push`, `replace`, `go`, `goForward` and `goBack` methods to actions.routing,
// when called, will dispatch the crresponding action provided by react-router-redux.
actions.routing = Object.keys(routerActions).reduce((memo, action) => {
memo[action] = (...args) => {
dispatch(routerActions[action](...args))
}
return memo
}, {})
// ConnectedRouter will use the store from Provider automatically
return (
<ConnectedRouter history={history}>
{children}
</ConnectedRouter>
)
}
怎么获取全局的store
有时候一些组件要跟 redux 集成在一起的话,需要额外添加 reducer,能支持就好啦
// store.js
function createReducer(models) {
const reducers = models.reduce((acc, cur) => {
acc[cur.name] = cur.reducer
return acc
}, {})
return combineReducers({
...reducers,
...defaultReducers, // some default reducer
routing: routerReducer
})
}
大概像这样的感觉,然后 defaultReducer 用一个 export 的函数添加?不知道是否可行。
First of all, I'd just like to say I like a lot of the design decisions in Mirror.js. Great work, with many improvements over DVA. I'll continue writing with an assumption that you may be familiar with DVAs API.
I have two suggestions that I would like to help create to bring both sagas with effects & an improved form of subscriptions to mirror.js. I believe this can be done without adding much additional weight to mirror.js.
One feature that remains missing is effects that run as sagas.
Using Mirror, sagas can still be used, but not within effects (as they are not running sagas).
I'm not at all suggesting copying the way effects are done in DVA. In DVA saga effects are passed in as the second param.
// within dva model
effects: {
*someEffect(action, effects) {
effects.put({ type: 'someAction' })
}
}
This isn't really necessary, since saga effects can be imported.
Note that I'm also not suggesting that redux-saga
should become a dependency of mirror.js.
In DVA, subscriptions run within a model on startup. These can be used to load data on startup of a model, among other uses.
When using sagas, it would be more effective if you could launch saga watchers on startup. Watchers are generator functions that allow you to create action listeners that trigger other functions. They can really help to keep your models from entangling each other with calls.
This is a two step process in DVA, (subscription calls an effect, effect calls a watcher). In DVA subscriptions are not sagas, but I would like to be able to overwrite how subscriptions work to make them into sagas as well.
// within dva model
subscriptions: {
*watch() {
// pause until a user is logged in
yield take('authenticated')
// listen for an action, and trigger an effect
yield takeEvery('someAction', put({ type: 'doSomething' })
}
}
This would create a very elegant and clear way to use sagas within a model.
Subscriptions could made to check if the function is a generator or not. Generators could run using a saga, whereas functions could run as normal.
What I would like to do is be able to overwrite how effects are handled as a default option. I'd also like to add subscriptions with an optional overwrite.
For example:
mirror.defaults({
effects: customEffectsHandler, // overwrite existing function
subscriptions: customSubscriptionHandler, // create additional function that runs on startup
middlewares: [sagaMiddleware],
})
I'd be happy to put in a PR for review, as well as to publish and maintain a mirror-saga
module separately.
Is it possible to have an event that can be listened by multiple models 😄
For example, I have a listener that fire action every time screen media query changed. This action needs to be listened by multiple ui state models
是否可以整合在server side render上面?
I think this project is great, is reduce a lot of boilerplate from redux
But 1 thing that should be improved is the ability to add custom reducer. Currently, I want to apply redux-form into my project but I have no method to attach redux form reducer into mirrorx
I think you can expose an API similar to hook
that add custom reducer
Thank you for your work
{
"peerDependencies": {
"react": ">=15",
"react-dom": ">=15",
"prop-types": ">=15"
},
}
我现在有三级组件:
level1组件(爷爷)--level2组件(儿子)--level3组件(孙子)
我在入口文件里注入了Mirror, 所以我可以在level1, level2组件和level3组件里自由的使用action.app.reducers,
但是我想在【level3组件】使用state时,就必须 level1里prop流向->level2里把prop流向->level3才可以~
有没有什么比较明显的区别?
如题,在组件中如何获取model的初始化参数及reducers中的方法。跨组件使用actions并没有出现app命名空间中的reducers 方法
希望可以看到对mirror项目的最佳实践
编译运行都没报错,但渲染出来的页面root里是空的
感觉很牛逼,做个测试项目玩玩
之前有个 create-react-app 的项目, 可以直接访问 /xxx,
在 mirror 下不行, 路由配置是一样的, 改过几次, 直接用两个 Route 也不能访问
historyMode: 'browser' 时会出现这样的情况
examples 里面的 router 不会有这样的情况
框架很简洁,也很好上手,不过 React-Router4 的 code split 社区找不到好的解决方案,请问能提供一下思路吗?
mirrorx 里面用了数组 find 及 includes 等等方法导致 ie 报错
给个小建议,就是可不可以把initialState换成state,这样会更简洁一点,写项目的的时候也更方便。而且vuex 也是用 state 来表示初始状态的,尽量保持一致吧。。。
What is the difference when compared to Jumpsuit?
I'd like to create a 'mirror-loading' package, similar to dva-loading. Basically it provides free "loading" indicators when effects are triggered or completed.
There should be a way in mirror to tell if an action handler is a "reducer" or an "effect". This way, "mirror-loading" can work with effects only.
This would be the simplest solution, but it doesn't seem elegant to expose more than necessary. Effects are already included in the list of actions.
// index.js
export default {
/* ... */
effects,
/* ... */
}
This would allow filtering over actions
to find which are effects. A rough outline of an example below:
// model.js
filterReducers(reducers) {
/* .... */
acc[action].prototype.effect = true
/* ... */
}
是否可以把同步action缩小调用范围,比如只能通过异步action进行调用。在我的一个项目中,所有数据请求都是通过异步action发起的,我不希望直接调用同步action更新state
\examples\simple-router\public\index.html中入口app.js引用为相对路径:
<script src="app.js"></script>
会导致地址栏直接输入路由地址(例如:localhost:8000/about/balabala)时404,建议改为绝对路径:
<script src="/app.js"></script>
如题,dva提供了类似subscriptions 用于监听url的变换从而进行一系列请求,然后将数据挂载在 model的 state上。但是mirrorx 获取数据时候可能要在组件didMount时候,然后再去定义一个方法去更新model state,两者对比各有各的好处,但是mirrorx是否可以增加像subscriptions的一个接口呢?
import React from "react";
import DemoList from "./DemoList";
import { Tabs } from "antd";
import mirror, { connect, actions, Route, Link } from "mirrorx";
const TabPane = Tabs.TabPane;
const createModel = function() {
let name = 'test' + parseInt(Math.random() * 10000) + ''
mirror.model({
name: name,
initialState: {
value: name
}
});
console.log(name)
return name;
};
mirror.model({
name: "demoaa",
initialState: {
tabs: []
},
reducers: {
addTab(state, data) {
let name = createModel();
let t = [].concat(state.tabs, [{ tab: (<Test value={name} />), key: name }])
console.log(t)
return {
...state,
tabs: t
};
}
}
});
const Test = (() => {
return connect(state => {
console.log(state);
return state;
})(props => {
{
console.log(props)
return (<div>{props[props.value].value}</div>)
}
});
})();
const DemoIndex = (() => {
return connect(state => {
return state.demoaa;
})(props => {
{
return (
<div>
<button
onClick={() => {
actions.demoaa.addTab()}
}
>
添加标签
</button>
<Tabs type="card">{props.tabs.map((item) => (<TabPane tab={item.key} key={item.key}>{item.tab}</TabPane>))}</Tabs>
</div>
)
}
})
})()
export default DemoIndex;
我希望通过动态的注册model,将Test控件绑定不同的数据,当然这个demo里面数据很简单,我们在项目中通过打开多个Tab里面会使用同一个component显示不同数据(例如不同的详情、新增),这时如果Test返回相同的state.xx的话会导致多个tab内component数据相同;或者是有其它什么解决方案么?
是否支持react native
有些场景需要多组件共用model,如果在container内分别connect,总感觉不太好。
在react-router v4中,react-router-dom包含了react-router的api,为什么要同时引用两个?
dva-loading极大的简化了loading状态管理
Line 3 in 5ca5031
跟文档描述有点不一致
mirror.defaults is a pretty intuitive API, you use it to configure your Mirror app.
- options.initialState
Default: undefined
options.initialState
如果默认是空对象,也比默认是undefined
要强吧~
我看不出这样做会有什么好处?
应该允许开发者自己根据业务情况去组合reducer,所以建议去掉这个feature,提供一个类似combineReducers
的 api 供开发者使用~
如果项目里需要创建很多model,现在每个model都需要进行mirror.model(xxxModel)。是否可以提供Redux中combineReducers类似的方式,一次性对所有model进行注入?
dva的不支持ie8,不知道mirror支持不?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.