Open haydn opened 3 years ago
@haydn Hey I'm not sure what you mean by this:
Dealing with nested state. What if layers could be organised into groups and those groups are nested recursively, how would we handle that in a Recoil world? (This should also answer the same question for options.)
I get that we want to test dealing with nested state and I can do that by testing how we've implemented the recursion through the options but I'm not sure what you mean by the rest of the statement.
I'm guessing that testing this using the recursion with options should be fine also for the sake of this but I just wanted to make sure.
@Mxchaeltrxn Yeah, we just want to test how we'd handle nested state. I was thinking of a hypothetical case like this might be easier to demonstrate in a minimal example, but feel free use the options if that works better:
const exampleDoc = {
type: "SketchbookDocument",
layers: [
{
id: "1",
type: "SketchbookComponent",
component: "Heading 1",
name: "Heading 1",
x1: 100,
y1: 100,
x2: 750,
y2: 140,
options: { text: "Example Heading 1" }
},
{
id: "2",
type: "SketchbookGroup",
name: "Example Group",
layers: [
{
id: "3",
type: "SketchbookComponent",
component: "Heading 2",
name: "Heading 2",
x1: 100,
y1: 200,
x2: 750,
y2: 240,
options: { text: "Example Heading 2" }
},
{
id: "4",
type: "SketchbookComponent",
component: "Paragraph",
name: "Paragraph",
x1: 100,
y1: 300,
x2: 750,
y2: 340,
options: { text: "Example Paragraph" }
}
]
}
]
};
@Mxchaeltrxn FYI, I'm also doing a similar investigation to see what it might look like if we used Immutable.js here: https://github.com/sketchbook-js/sketchbook/issues/126
@haydn Hey thanks for letting me know! I've been a bit busy recently but will be back on this on this Wednesday.
@haydn I've investigated the first 4 parts of this and I'll do the last one a bit later. Just putting this here so you have some time to look at it first.
Visually, it's a bit ugly but I think it does the job. Here is the sandbox.
I didn't use your sandbox (for better or worse) because I felt it was slightly more complicated but I may use it for the postMessage
section. Thanks for making it though!
Brief explanation of the UI:
LAYERS
--------------------------------
--------------------------------
Layer 1
options for layer 1
--------------------------------
options for layer 1 (again)
--------------------------------
--------------------------------
Layer 2 ... (repeat of above)
To test:
Edit layer id
button.Findings: Only the layer that was edited is edited (look at the layer name to check) and the timestamp should correspond to the time that you clicked the button.
Option
rerenders.Edit option id
button for any option.Findings: Only the option id for the selected option changes (for both lists that I've rendered). Only those two options rerender; the layer and the document don't rerender.
I've implemented something similar to what we have in sketchbook (but I've done some hardcoding here).
"value":["nested 0,0","nested 0,1"]
Findings: array that contains that option rerenders in both the top and bottom options for Layer 1.
I didn't do a demo for this because I think I understand how to implement this (if you're still unsure then I can make something because I could be assuming things). My understanding is that we can use selectors to create derived state (which I believe is the general case for what you want when you say you want to combine state1 and state2 to calculate something else). Selector example from the Recoil docs:
const mySelector = selector({
key: 'MySelector',
get: ({get}) => get(myAtom) * 100,
});
We can pass in normally handled react state (or just any variables we want) like so:
const mySelector = (NORMALLY_HANDLED_REACT_STATE) => selector({
key: 'MySelector',
get: ({get}) => get(myAtom) * 100,
});
I'm unsure of this will have any performance impacts though.
Also this video by one of the creators was a good watch to get to know the Recoil library a bit more
Hypothesis
Using Recoil to maintain the app's state will improve performance (especially for documents that have a lot of layers) and also provide a useful pattern for dealing with nested state.
Deliverables
Put together a CodeSandbox or two to test how Recoil will work with some of the key pieces of functionality.
Specific things to test:
postMessage()
to sync the editor state to the canvas state which uses the structured clone algorithm to copy the data. Would we be able send Recoil's data with that or would we need to transform it into a simpler form first?Notes