Replies: 6 comments 5 replies
-
This could be a good line in the sand for introducing context, I think that a lot of the concerns around context was that unmanaged use of global state would make the code hard to reason about especially if we ever needed to migrate away from DCR. However, using context solely to hold static values specific to an individual render makes sense to me. Something that will need to be figured out though is how to support islands when using react context - I'm guessing each island will need a context provider, which also means the islands hydration code will also need to know what was in context during the server-side-render, definitely would love to see a proof-of-concept around how that might work! |
Beta Was this translation helpful? Give feedback.
-
I think this is a great opportunity to test out context in the DCR codebase. As Olly mentioned, we should make sure we are strict / have lines in the sand about when we use context vs prop drilling to avoid mystifying the code base but a static value like the renderingTarget makes total sense. |
Beta Was this translation helpful? Give feedback.
-
There's some extra food for thought from @bryophyta. And the original PR that sparked this ADR. Paraphrasing @nicl's original comment
Looking at each point individually: 1. ReadabilityI am unsure this is the case, especially given that prop-drilling introduces it's own readability and ability to decern where a property is actually introduces vs used. I think a PR as suggested would really help decide this 2. Global stateOn @OllysCoding's point, it would be good to decide what is allowed into this global state e.g. it is static, it is truly global etc. We could reference this line in the side next the the generating code to help reviewers in the future consider their choice. 3. ReactI would say we're pretty coupled. Not sure what others think? 4. ComposabilityThis is an interesting point, but This also assumes that we have a shallow component tree, which is mentioned above, which isn't true given the size of the PRs that have instigated this. e.g. flowchart LR
Root-->|drills prop1| Component1-->|drills prop1| Component2-->|drills prop1| Component3-->|drills prop1| Component4["Component using prop 1"]
But now only flowchart LR
Root-->|"setContext(prop1)"| Component1--> Component2--> Component3--> Component4["Component useProp1()"]
As mentioned a lot above, I think defining the line in the sand will probably be the fun / tricky bit. |
Beta Was this translation helpful? Give feedback.
-
As others have said if we do use context we need some strict lines (context allowlist?) in the sand. I wonder if one of the rules should be that we don't use context on the client. Working out why re-renders happen can be tricky at the best of times. If we are using context on the client and getting re-renders from context updates that will be harder still. I do worry however that over time in order to avoid prop drilling, context is used as an escape hatch and we will start to put more and more props into context. Prop drilling can be tedious but it is very explicit and makes reasoning about what props a component required much simpler. |
Beta Was this translation helpful? Give feedback.
-
Here's a suggestion of a way forward, using React Context for very generic rendering state where:
It does assume that most of the time, we'll be dealing with It would be worth drafting a doc on what our lines in the sand are and then linking this in the context docstring to avoid overzealous use of context where it may not be the best choice for a solution. Based on the comments on this thread already, here's an attempt:
Any help on the documentation of this would be much appreciated! |
Beta Was this translation helpful? Give feedback.
-
Thanks everyone for participating in this discussion! The PR suggesting implementation for this (#8704) has been merged, with an additional issue here (#8795) to improve the efficiency of the islands code (not completed at the time of writing). I'm going to close this discussion since we have reached a resolution, which is now documented in the code base ✨ |
Beta Was this translation helpful? Give feedback.
-
There was an RFC put together earlier this year about how to go about implementing
renderingTarget
in DCR for apps work:#7256
In this issue, it mentions the following:
The fact that we don't use React Context or global state in DCR is not strictly true as it's used here:
dotcom-rendering/dotcom-rendering/src/components/ContentABTest.amp.tsx
Lines 47 to 94 in fd2beca
There are a number of ADRs from 2019 discussing React Context and why it was decided to largely avoid using it:
The main ADR says
Given that the codebase has grown considerably since 2019 and is still growing, it would be worth revisiting whether React Context could be useful in certain situations.
Specifically, it is worth considering using React Context for the case of
renderingTarget
(currently either"Web"
or"Apps"
) as it is set at the entrypoint only and will not change throughout the component lifecycle.Having started working on implementing
renderingTarget
for Bridget work as a team, PRs are becoming exhaustingly long due to unnecessary changes relating to prop drilling, both in terms of writing code and reviewing it.This has prompted this discussion and a revisit to the prior decision of not using contexts in DCR.
Beta Was this translation helpful? Give feedback.
All reactions