Comments (21)
@danielmiladinov @meta-meta @lijunle What do you guys think?
from react-cursor.
I don't fully get your meaning? How will the usage syntax look like after this change?
Will it look same as immutable.js way?
Will user need to call setState by his own code?
It could be great to provide some usage snippets.
Thanks!
from react-cursor.
We'd stop using React state completely, all data is above the React root and passed down as props by React.render. The Cursor constructor would be passed a reference to state value, and a setState function. Those can either be a React cmp.state and cmp.setState, or we can pass in our own reference and our own setState function that mutates the reference with updated state (no react dependency). In the non-react case, we'd have to handle re-rendering and render batching ourselves, like in ClojureScript world. I don't know how people using immutablejs handle batching but presumably its similar.
from react-cursor.
That is awesome. Cursor is passed from React.render function and I do not need to specially treat root component and sub-component any more.
But, AFAIK, on the React.render level, there is no way to get setState function before invoke render function.
Such syntax?
var cursor = Cursor.build(data) // no way to get setState function here
var cmp = React.render(App, cursor, dom)
cursor.initSetState(cmp.setState)
from react-cursor.
To directly answer your question, here is one way: https://github.com/mquan/cortex/blob/master/examples/skyline/application.jsx#L107-L113
Another way
var state = { a: { b: 42 }}; // this reference owns the state, like a singleton
var cursor = Cursor.build(state);
React.render(<App cursor={cursor}/>, domEl)
cursor.onUpdates((cursor) => React.render(<App cursor={cursor}/>, domEl))
// onUpdates needs to implement batching strategy
from react-cursor.
@dustingetz Your sample code is awesome!
I have two issues.
- How about delegate the first render inside
onUpdate
method and rename it to something likeinitUpdate
- React itself has already implement the batching strategy. I could prefer to leave these jobs for React and do nothing in cursor level.
from react-cursor.
React itself has already implement the batching strategy. I could prefer to leave these jobs for React and do nothing in cursor level.
I agree but I think this is incompatible with this approach? If I understand correctly, React batching strategy requires us use react setState. I might be wrong.
from react-cursor.
I search on the React source code, the answer is no.
The render
function find if the element is mounted. If yes, only update the changes. Inside update function, React push the changes to the queue.
from react-cursor.
So if I understand correctly, this sample code will batch properly with no extra code?
cursor.onUpdates((cursor) => React.render(<App cursor={cursor}/>, domEl))
from react-cursor.
I think so.
from react-cursor.
@dustingetz I purpose the usage syntax, and update the examples and unit tests. How do you think about it? dustingetz:master...lijunle:v2
(Note: no production code changes, tests will fail.)
from react-cursor.
I'm still thinking about the best way to implement this. I'm currently thinking:
Two cursor types (scala syntax): ReactStateCursor(cmp: ReactComponent)
and PlainCursor(value: JsObject, swapper: JsObject => ())
. ReactStateCursor
is just PlainCursor(cmp.state, cmp.setState)
. This way I can retain backwards compatibility with existing code, because one design goal of react-cursor is to be fast and easy to integrate with largish React apps that are already using React state. Then an application can derive custom Cursor types as needed, like BatchingReactCursor, BatchingPlainCursor, ReactCursorWithPendingValue (#57) etc.
from react-cursor.
Are you meaning that, make some inheritance with various Cursor variants?
PlainCursor
/ \
/ \
ReactStateCursor (customized) MyPlainCursor
/ \
/ \
BatchingCursor PendingValueCursor
After that, PlainCursor and ReactStateCursor are shipped inside this package. Everybody can customize based on them.
In such case, how do you handle Cursor.build
API, wrap new ReactStateCursor
initialization?
from react-cursor.
Conceptually, yes. I would prefer composition to inheritance if possible. It's not yet clear to me the best way to handle cursor.build.
from react-cursor.
How about this?
From the user aspect (API aspect).
Keep Cursor.build
as the current behavior for backward compatible (wrap new ReactStateCursor
). This is V1 usage style.
Document and recommend the V2 usage style:
const cursor = new Cursor({ ...initial state data... }); // or use other function, i.e., Cursor.create. We can discuss
cursor.init(() => React.render(<App cursor={cursor} />, dom));
Common users only use these two APIs - V1 style for Cursor.build
function, V2 style for Cursor constructor.
Internally (advanced user aspect)
Build up with inheritance as described above, but document it as advanced features.
Currently, the only one API exposed is Cursor.build
function, I think such upgrade is smooth and easily understand.
from react-cursor.
Is v2 public api (new
to construct cursor) compatible with the memoizing strategy?
from react-cursor.
I am not sure, but I think it can be compatible.
from react-cursor.
I have this working locally:
var state = {
very: {
deeply: {
nested: {
counts: _.range(400).map(function () { return 0; })
}
}
}
};
function swapper(f) {
state = f(state);
queueRender();
}
function queueRender() {
var cur = ReactCursor.Cursor.build(state, swapper);
React.render(<App cursor={cur} />, document.getElementById('root'));
}
queueRender();
from react-cursor.
The latest api supports regular cursors (immutable value semantics for react lifecycle methods and shouldComponentUpdate) and also now RefCursors which are for business logic type code that only ever cares about the latest value and doesn't expose a notion of value equality since it is not in react lifecycle methods.
window.stateAtom = atom.createAtom({
very: {
deeply: {
nested: {
counts: _.range(400).map(function () { return 0; })
}
}
}
});
function queueRender(key, ref, prevVal, curVal) {
var cur = ReactCursor.Cursor.build(stateAtom.deref(), stateAtom.swap);
window.app = React.render(<App cursor={cur} />, document.getElementById('root'));
}
stateAtom.addWatch('react-renderer', queueRender);
queueRender('react-renderer', stateAtom, undefined, stateAtom.deref());
var cur = ReactCursor.Cursor.build(stateAtom.deref(), stateAtom.swap)
var refcur = ReactCursor.RefCursor.build(stateAtom.deref, stateAtom.swap)
cur.refine('very', 'deeply', 'nested', 'counts', 0).value // => 0
refcur.refine('very', 'deeply', 'nested', 'counts', 0).deref() // => 0
cur.refine('very', 'deeply', 'nested', 'counts', 0).set(100)
// Regular value cursors are not changed since immutable and have value semantics
cur.refine('very', 'deeply', 'nested', 'counts', 0).value // => 0
// Reference cursors see latest value
refcur.refine('very', 'deeply', 'nested', 'counts', 0).deref() // => 100
from react-cursor.
(This is not merged, see #63)
from react-cursor.
Fixed in 2.0-alpha.4
from react-cursor.
Related Issues (20)
- destroy function? HOT 4
- warning using React 14 dev build HOT 5
- can a refined cursor call forceUpdate on the proper react node to bypass trickle down rendering? HOT 2
- improve build targets HOT 2
- 2.0 branch broke cursor ref equality against react components HOT 1
- extract react-addons-update wrapper into a standalone library
- update react-json-editor example
- ImmutableOptimizations needs default argments
- implement refToHash with weakmap
- discus flux in the readme HOT 1
- The unminified build does not produce a UMD module HOT 1
- ImmutableOptimizations should respect react state HOT 1
- Add example as jsfiddle HOT 10
- Make ImmutableOptimizations available without a mixin
- Add assertion preventing function references inside cursors HOT 2
- remove omit-keys dependency, clean up util.js HOT 1
- add syntax sugar for remove-at-index HOT 2
- allow refine&set to create key if not existant HOT 2
- Problem with fresh npm install HOT 7
- document WeakMap dependency (or polyfill)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-cursor.