byte-fe / react-model Goto Github PK
View Code? Open in Web Editor NEWThe next generation state management library for React
The next generation state management library for React
🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨
To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.
Since we didn’t receive a CI status on the greenkeeper/initial
branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.
If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/
.
Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.
devDependency
@commitlint/cli was updated from 8.0.0
to 8.1.0
.devDependency
@commitlint/config-conventional was updated from 8.0.0
to 8.1.0
.This version is covered by your current version range and after updating it in your project the build failed.
This monorepo update includes releases of one or more dependencies which all belong to the commitlint group definition.
commitlint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
The new version differs by 39 commits.
c17420d
v8.1.0
ca19d70
chore: update dependency lodash to v4.17.14 (#724)
5757ef2
build(deps): bump lodash.template from 4.4.0 to 4.5.0 (#721)
5b5f855
build(deps): bump lodash.merge from 4.6.0 to 4.6.2 (#722)
4cb979d
build(deps): bump lodash from 4.17.11 to 4.17.13 (#723)
a89c1ba
chore: add devcontainer setup
9aa5709
chore: pin dependencies (#714)
c9ef5e2
chore: centralize typescript and jest setups (#710)
c9dcf1a
chore: pin dependencies (#708)
6a6a8b0
refactor: rewrite top level to typescript (#679)
0fedbc0
chore: update dependency @types/jest to v24.0.15 (#694)
0b9c7ed
chore: update dependency typescript to v3.5.2 (#695)
4efb34b
chore: update dependency globby to v10 (#705)
804af8b
chore: update dependency lint-staged to v8.2.1 (#696)
9075844
fix: add explicit dependency on chalk (#687)
There are 39 commits in total.
See the full diff
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
I have a:
Provide a minimal sample reproduction. Create a reproduction based on this sandbox 🚀
Did you check this issue wasn't filed before? 🤔
Not filed before.
Elaborate on your issue. What behavior did you expect? ❓
No error
State the versions of react-model and relevant libraries. Which browser / node / ... version? 🚧
Software | Version(s) |
---|---|
react-model | v2.4.1 - v2.5.2 |
Node | v10.15.0 |
react | v16.8.4 |
Operating System | macOS |
TypeError: Cannot read property 'state' of undefined
j
node_modules/react-model/dist/react-model.js:253
250 | }), e;
251 | },
252 | j = function j(t, e) {
253 | var r = n.useState(o.State[t].state)[1];
254 | o.uid += 1;
255 | var c = "" + o.uid;
256 | o.Setter.functionSetter[t] || (o.Setter.functionSetter[t] = {}), o.Setter.functionSetter[t][c] = {
View compiled
WorkSpaceList
src/views/Pages/WorkSpace/List/index.tsx:16
13 | star: boolean,
14 | members: string[]
15 | }
16 | const WorkSpaceList = () => {
17 | const [newDialogVisible, setNewDialogVisible] = useState(false);
18 | const [state, actions] = useStore('WorkSpaceList');
19 |
Cause of the __hash
function setter has been executed in stateUpdater: Middleware
we don't need to executed this __hash
state update again in communicator
middleware, i think it should be changed to
if (Global.Setter.functionSetter[modelName]) {
Object.keys(Global.Setter.functionSetter[modelName]).map((hash) => {
const setter = Global.Setter.functionSetter[modelName][hash];
// If we need to exclude executed `setter` from `stateUpdater`
// we should exclude `__hash` once __hash has been executed in `stateUpdatater` middleware.
if (setter && __hash !== hash) {
if (!setter.selector) {
setter.setState(Global.State[modelName]);
} else {
const newSelectorRef = setter.selector(Global.State[modelName]);
if (!shallowEqual(newSelectorRef, setter.selectorRef)) {
setter.selectorRef = newSelectorRef;
setter.setState(Global.State[modelName]);
}
}
}
});
}
我有一个:
https://github.com/byte-fe/react-model-experiment/blob/master/pages/_app.tsx
modelName 这个参数不是制定要获取的model的state吗?我发现无论传什么或者不传,返回的都是全部的models state
12.12.1
to 12.12.2
.This version is covered by your current version range and after updating it in your project the build failed.
@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
8.0.7
to 8.0.8
.This version is covered by your current version range and after updating it in your project the build failed.
@testing-library/react is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
The new version differs by 7 commits.
98b9605
Update FUNDING.yml
1eae361
fix: make cleanup use async act (#427)
4c8ca23
docs: add alejandroperea as a contributor (#425)
3ef5361
docs: add JSFernandes as a contributor (#424)
54d060b
docs: Document known issue with React 16.8 (#423)
edd3eaa
docs: add jamesgeorge007 as a contributor (#421)
709eb75
docs: make the license text point to the respective file (#420)
See the full diff
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
In order to use Hooks in RN, you need to upgrade to v0.59.x or build react with --type=RN_OSS manually and replace the old Render in node_modules ...
These are difficult for the most react-native user. It may need much time and make developer hard to use and migrate by using the api(Provider, connect) now.
Consider to provider more powerful api (connect, Provider) for class components.
The plan contains:
I have a problem when I use [email protected] in my ts project
the debug in console prints the saved and also changed state from localStorage. but it not get initialized with the initalValue
- only with the defaultUser
:/
export interface User {
trips: Trip[];
name: string;
id: number;
}
const defaultUser: User = {
id: defaultTrips.length + 1,
name: "User1",
trips: defaultTrips
};
interface StateType {
user: User;
}
const model: ModelType<StateType, ActionParams> = {
state: {
user: defaultUser
},
actions: {
// actions here
}
}
const persistMiddleware: Middleware = async (context, restMiddlewares) => {
localStorage.setItem('__REACT_MODEL__', JSON.stringify(context.Global.State))
await context.next(restMiddlewares)
}
actionMiddlewares.push(persistMiddleware)
let initalValue = JSON.parse(localStorage.getItem('__REACT_MODEL__')||"{}");
console.log("initial: start")
console.log(initalValue); // here the changed and saved State is printed
console.log("initial: end")
export default Model(model, initalValue)
我有一个:
// declaration
export const { getStore } = createStore(() => {...})
// usage
function App() {
useEffect(() => {
console.log(getStore())
}, [])
}
* [ ] 你认为它应该被集成在这个库中,还是以文档的方式说明,还是其他方式体现? 💡
* [ ] 你是否乐意自己提PR来完成这个feature呢? ⚔
勾选你的问题所属的类型,issue模板中其他无关的部分记得删除哦
issue被解决后,希望你可以及时关闭issue :)
The state from useStore should rerender only when the specific actions executed.
function useEffect(effect: EffectCallback, deps?: DependencyList): void;
function useStore(name: string, depActions?: string): [State, Actions];
To prevent logs triggered by some specific type of actions which may be disturbing in console
import { middlewares } from 'react-model'
middlewares.config.logger.enable = ({modelName, actionName}) => ['aaa'].indexOf(actionName) !== -1
Sometimes we want to watch a store state and do some effects
like this, by easy-peasy https://easy-peasy.vercel.app/docs/api/effect-on.html
export default createStore({
items: [],
saving: false,
setSaving: action((state, payload) => {
state.saving = payload;
}),
addItems: action((state, payload) => {
state.items.push(payload);
}),
stateChange: unstable_effectOn(
[(state) => state.items],
async (actions, change) => {
const [items] = change.current;
actions.setSaving(true);
await todosService.save(items);
actions.setSaving(false);
}
)
});
in the react-model v4, we usually write it like this
export const { useStore } = createStore(() => {
const [todoItems, setTodoItems] = useModel<string[]>([])
const [saving, setSaving] = useModel<boolean>(false)
const addItems = useCallback((item) => setTodoItems(todoItems => todoItems.push(item)), [])
// it will register repeatedly
// so may be provide a new store effect hook just execute once
useEffect(() => {
setSaving(true);
await todosService.save(todoItems);
setSaving(false);
}, [todoItems])
return {
todoItems,
saving,
addItems
}
})
Sometimes we need to pass request info to send requests when use SSR. Like:
MyApp.getInitialProps = async ({ req }) => {
if (!(process as any).browser) {
const initialModels = await getInitialState(req)
return { initialModels }
} else {
return { persistModel }
}
}
Support passing params to getInitialState.
Don't support.
Every useStore create a setState now. The cost of communicator middleware will be expensive when the new state passed in setState is huge and the number of components(use useStore hooks) is big.
Enhance:
// before
const useStore = (modelName: string, depActions?: string[]) => {
const [, setState] = useState(Global.State[modelName].state)
// ...
}
// expected
const useStore = (modelName: string, depActions?: string[]) => {
// If Context exist
const { [modelName]: { setState } } = useContext(GlobalContext)
// If not
const [, setState] = useState(Global.State[modelName].state)
// ...
}
Upon startup, I always see an error along the lines of "We recommend you to use NextModel now...".
Is this just a 'type' error? As in, does it warn if a model is not defined as the NextModel type?
And if so, is it possible to avoid that error if not using TypeScript?
There are duplicate repos when searching from Google react-model
Think about the current version vs koa middleware, we've implemented it as an array and it make confusing and chaos here, I think koa middleware is a classic model looks simple and easily to use.
how does it look like
const model = Model(models)
model.use(async (ctx, next) => {
console.log('1')
await next()
console.log('2')
})
model.use(async (ctx, next) => {
console.log('3')
await next()
console.log('4')
})
// 1->3->change state->4->2
It support enhance before and after state change, we should define a middleware interface and provider the most impotant middlewares, no need subscribe
api here.
import Model, { middlewares } from 'react-model'
const model = Model(models)
model.use(middlewares.logger())
model.use(middlewares.devTool())
middlewares should works with different model:
const modelA = Model({})
const modelB = Model({})
modelA.use(middlewares.logger())
modelB.use(middlewares.devTool())
const { useStoreA } from modelA
const { useStoreB } from modelB
Updated 2019-3-39
I have a:
What problem would it solve for you? 🐛
These days, I review the model layer code in our teams and found something awkward.
Form.ts
const model = {
// ...
actions: {
updateA: (s, _, payload) => { ... },
updateB: (s, _, payload) => { ... },
updateC: (s, _, payload) => { ... },
updateD: (s, _, payload) => { ... }
}
}
🤦♀️actions is useless at the most cases, and actions is also the return value of Model now, so why should we write _ again and again?
The better we I thought:
v2.x (no breaking changes, only new usage added, log warning for old usage)
Form.ts
import { actions } from './index.model'
const model = Model({
// ...
actions: {
updateA: (payload, ctx) => { ... },
updateB: (payload, ctx) => {
const { state, actions } = ctx
actions.Form.updateA()
// ...
},
updateC: (payload, ctx) => { ... },
updateD: (payload, ctx) => { ... }
}
})
const subscription = model.subscribe('updateA', () => { ... })
setTimeout(() => { subscription.unsubscribe() })
export default model
v3.x
Drop old object usage.
Do you think others will benefit from this change as well and it should in core package? 💡 Yes
Are you willing to (attempt) a PR yourself? ⚔
Yes
What do you think of it? Vote by yourself!
const Button = connect(
'Counter',
(props: any) => props
)(
class extends React.PureComponent<any> {
render() {
const { state, actions, buttonName = '' } = this.props
return (
<button
onClick={() => {
actions.increment(3).catch((e: any) => console.error(e))
}}
>
{buttonName}
{state.count}
</button>
)
}
}
)
<Provider>
<Button buttonName="button" />
</Provider>
expect(button!.textContent).toBe('button0')
12.7.0
to 12.7.1
.This version is covered by your current version range and after updating it in your project the build failed.
@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Sometimes we have one state and its value will be changed if and only if another state is changed. Nowadays we have to update their states manually in actions, for instance:
{
state: {
num: 3,
sqauredNum: 9
},
actions: {
setNum: num => {
return state => {
state.num = num
state.sqauredNum = num * num
}
}
}
}
Is there a way to manage only core states and make the derived states (like sqauredNum
) be re-calculated automatically (like Selectors in https://recoiljs.org/docs/introduction/core-concepts)
const defaultFunc = () => {}
{
state: {
num: 3,
sqauredNum: ({ num }) => num * num // calculated state
func: defaultFunc // function handler
}
}
...
const App = () => {
const [{ sqauredNum }] = useStore('xxx')
// use sqauredNum
}
I have a:
First of all, it is great great lib! After many others, I appreciate all the features here!
Another documentation that I can add, is the neat feature - as an example if you push into array but in the component you use the first element, then the component won't be updated.
[ x] Documentation improvement. Creating a PR if you can👏.
Please tick the appropriate boxes. Feel free to remove the other sections.
Please be sure to close your issues promptly.
如果不处理会报localStorage is not defined
之类的错误。
是否有开关可以自定义中间件在server/browser阶段执行?
用的next.js。
openLight: async (state, actions) => {
await actions.increment(1) // You can use other actions within the model
await actions.get() // support async functions (block actions)
actions.get()
await actions.increment(1) // + 1
await actions.increment(1) // + 2
await actions.increment(1) // + 3 as expected !
return { light: !state.light }
},
openLight function doesn't wait action.get() finish to execute the follow actions.
Why you don't maintain your repository https://github.com/leecade/react-native-swiper?
If you don't have much time to that maybe should move it to community repo ?
I have a:
Issue:
Provide error messages including stacktrace ❌
Provide a minimal sample reproduction. Create a reproduction based on this sandbox 🚀
Did you check this issue wasn't filed before? 🤔
Elaborate on your issue. What behavior did you expect? ❓
State the versions of react-model and relevant libraries. Which browser / node / ... version? 🚧
TypeScript error in /Users/muescha/Work/react/xxx/node_modules/react-model/src/helper.ts(46,10):
Property 'entries' does not exist on type 'ObjectConstructor'. TS2339
44 | ) => {
45 | const ret: any = {}
> 46 | Object.entries<Action>(actions).forEach(([key, action]) => {
| ^
47 | ret[key] = consumerAction(action, modelContext)
48 | })
49 | return ret
| Software | Version(s) |
| ---------------- | ---------- |
| react-model | 3.0.1 |
| Node | v10.15.3 |
| react | 16.9.0 |
| Operating System | 10.14.5 (18F132) macOS MOjave |
├── @types/[email protected] invalid
├── @types/[email protected] invalid
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
I have a:
Idea:
What problem would it solve for you? 🐛
Developer can subscribe the state changes.
v2.x api
// subscribe actions
// (storeName, actionList, callback) => void
subscribe('Counter', ['increment'], () => (count += 1))
// subscribe properties changes
// (storeName, mapStateFunction, callback) => void
subscribe('Counter', state => state.count, () => alert('counter count change!'))
v3.x api
const store = Store({
// ...
actions: {
updateA: (s, payload) => { ... },
updateC: (s, payload) => { ... },
updateD: (s, payload) => { ... }
}
})
// subscribe actions
store.subscribe(['updateA'], () => (count += 1))
// subscribe properties changes
store.subscribe(state => state.A, () => alert('A change!'))
Do you think others will benefit from this change as well and it should in core package? 💡 Yes
Are you willing to (attempt) a PR yourself? ⚔
Yes
16.8.24
to 16.8.25
.This version is covered by your current version range and after updating it in your project the build failed.
@types/react is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
5.3.2
to 5.3.3
.This version is covered by your current version range and after updating it in your project the build failed.
immer is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
When you are developing your web application, you have to perform asynchronous operations,
e.g. perform a fetch/ajax call to obtain data from the server. Sometimes you need to do silent background operations,
whereas in other cases you need to block the user interface or notify them that something is going on.
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.