-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from li3zhen1/state_mixin
[Doc] Add State Management and Eliminating Redundant Rerenders
- Loading branch information
Showing
2 changed files
with
78 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
Sources/Grape/Grape.docc/StateManagementAndEliminatingRedundantRerenders.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# State Management and Eliminating Redundant Rerenders | ||
|
||
|
||
|
||
## Control the state | ||
|
||
You can control the view state like this: | ||
|
||
```swift | ||
import Grape | ||
|
||
struct MyStatefulGraph: View { | ||
|
||
// States including running status, transformation, etc. | ||
// Gives you a handle to control the states. | ||
@State var graphStates = ForceDirectedGraphState() | ||
|
||
var body: some View { | ||
ForceDirectedGraph(states: graphStates) { | ||
// ... | ||
} force: { | ||
// ... | ||
} | ||
} | ||
} | ||
``` | ||
|
||
`ForceDirectedGraphState` utilizes the `Observation` framework so all you need to change the state is to mutate its properties: | ||
|
||
```swift | ||
|
||
graphStates.isRunning.toggle() | ||
|
||
graphStates.transform = .identity // reset transform to identity | ||
|
||
``` | ||
|
||
## Eliminate redundant rerenders | ||
|
||
One trick to eliminate redundant rerenders is to not referencing any observed properties in the `body` of the `View`. Instead, try to reference the entire `Observable` object. This way, the `body` will not rerender when the observed properties change. | ||
|
||
```swift | ||
import Grape | ||
|
||
struct MyStatefulGraph: View { | ||
|
||
// States including running status, transformation, etc. | ||
// Gives you a handle to control the states. | ||
@State var graphStates = ForceDirectedGraphState() | ||
|
||
var body: some View { | ||
HStack { | ||
ForceDirectedGraph(states: graphStates) { | ||
// ... | ||
} force: { | ||
// ... | ||
} | ||
GraphStateToggle(graphStates: graphStates) // seperate views so we can reference the entire graphStates | ||
} | ||
} | ||
} | ||
|
||
struct GraphStateToggle: View { | ||
@Bindable var graphStates: ForceDirectedGraphState | ||
var body: some View { | ||
Button { | ||
graphStates.isRunning.toggle() | ||
} label: { | ||
// ... | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Although this introduces boilerplates, but `Grape` do benifit from this pattern since its re-evaluation is expensive (especially with large graphs or heavy rich text labels). | ||
|
||
> This might not always work for other `Observation` based state management. |