@khanacademy/wonder-blocks-core 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-core
|
|
2
2
|
|
|
3
|
+
## 4.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0aed8723: Adds `throwIfNested` required prop to `RenderStateRoot`.
|
|
8
|
+
|
|
3
9
|
## 4.1.0
|
|
10
|
+
|
|
4
11
|
### Minor Changes
|
|
5
12
|
|
|
6
|
-
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
- 45588e5f: Fix an issue with `useUniqueIdWithMock`/`useUniqueIdWithoutMock`
|
|
14
|
+
rerender more than was needed. The fix introduces `<RenderStateRoot>`
|
|
15
|
+
which must be an ancestor to all components uses these hooks.
|
|
16
|
+
- 875b7893: Nesting of `RenderStateRoot`s inside each other can result in extra renders
|
|
17
|
+
and potentially incorrect behavior. `RenderStateRoot` now throws if it
|
|
18
|
+
appears as a descendent of another `RenderStateRoot`.
|
package/dist/es/index.js
CHANGED
|
@@ -688,23 +688,32 @@ const {
|
|
|
688
688
|
useState
|
|
689
689
|
} = React;
|
|
690
690
|
const RenderStateRoot = ({
|
|
691
|
-
children
|
|
691
|
+
children,
|
|
692
|
+
throwIfNested
|
|
692
693
|
}) => {
|
|
693
694
|
const [firstRender, setFirstRender] = useState(true);
|
|
694
695
|
const contextValue = useContext(RenderStateContext);
|
|
695
|
-
|
|
696
|
-
if (contextValue !== RenderState.Root) {
|
|
697
|
-
throw new Error("There's already a <RenderStateRoot> above this instance in " + "the render tree. This instance should be removed.");
|
|
698
|
-
}
|
|
699
|
-
|
|
700
696
|
useEffect(() => {
|
|
701
697
|
setFirstRender(false);
|
|
702
698
|
}, []); // This effect will only run once.
|
|
703
699
|
|
|
700
|
+
if (contextValue !== RenderState.Root) {
|
|
701
|
+
if (throwIfNested) {
|
|
702
|
+
throw new Error("There's already a <RenderStateRoot> above this instance in " + "the render tree. This instance should be removed.");
|
|
703
|
+
} // Avoid rendering multiple providers if this RenderStateRoot
|
|
704
|
+
// is nested inside another one.
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
return children;
|
|
708
|
+
}
|
|
709
|
+
|
|
704
710
|
const value = firstRender ? RenderState.Initial : RenderState.Standard;
|
|
705
711
|
return /*#__PURE__*/React.createElement(RenderStateContext.Provider, {
|
|
706
712
|
value: value
|
|
707
713
|
}, children);
|
|
708
714
|
};
|
|
715
|
+
RenderStateRoot.defaultProps = {
|
|
716
|
+
throwIfNested: true
|
|
717
|
+
};
|
|
709
718
|
|
|
710
719
|
export { IDProvider, RenderStateRoot, server as Server, Text, UniqueIDProvider, View, WithSSRPlaceholder, addStyle, useUniqueIdWithMock, useUniqueIdWithoutMock };
|
package/dist/index.js
CHANGED
|
@@ -934,24 +934,33 @@ const {
|
|
|
934
934
|
useState
|
|
935
935
|
} = react__WEBPACK_IMPORTED_MODULE_0__;
|
|
936
936
|
const RenderStateRoot = ({
|
|
937
|
-
children
|
|
937
|
+
children,
|
|
938
|
+
throwIfNested
|
|
938
939
|
}) => {
|
|
939
940
|
const [firstRender, setFirstRender] = useState(true);
|
|
940
941
|
const contextValue = useContext(_render_state_context_js__WEBPACK_IMPORTED_MODULE_1__[/* RenderStateContext */ "b"]);
|
|
941
|
-
|
|
942
|
-
if (contextValue !== _render_state_context_js__WEBPACK_IMPORTED_MODULE_1__[/* RenderState */ "a"].Root) {
|
|
943
|
-
throw new Error("There's already a <RenderStateRoot> above this instance in " + "the render tree. This instance should be removed.");
|
|
944
|
-
}
|
|
945
|
-
|
|
946
942
|
useEffect(() => {
|
|
947
943
|
setFirstRender(false);
|
|
948
944
|
}, []); // This effect will only run once.
|
|
949
945
|
|
|
946
|
+
if (contextValue !== _render_state_context_js__WEBPACK_IMPORTED_MODULE_1__[/* RenderState */ "a"].Root) {
|
|
947
|
+
if (throwIfNested) {
|
|
948
|
+
throw new Error("There's already a <RenderStateRoot> above this instance in " + "the render tree. This instance should be removed.");
|
|
949
|
+
} // Avoid rendering multiple providers if this RenderStateRoot
|
|
950
|
+
// is nested inside another one.
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
return children;
|
|
954
|
+
}
|
|
955
|
+
|
|
950
956
|
const value = firstRender ? _render_state_context_js__WEBPACK_IMPORTED_MODULE_1__[/* RenderState */ "a"].Initial : _render_state_context_js__WEBPACK_IMPORTED_MODULE_1__[/* RenderState */ "a"].Standard;
|
|
951
957
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_render_state_context_js__WEBPACK_IMPORTED_MODULE_1__[/* RenderStateContext */ "b"].Provider, {
|
|
952
958
|
value: value
|
|
953
959
|
}, children);
|
|
954
960
|
};
|
|
961
|
+
RenderStateRoot.defaultProps = {
|
|
962
|
+
throwIfNested: true
|
|
963
|
+
};
|
|
955
964
|
|
|
956
965
|
/***/ }),
|
|
957
966
|
/* 15 */
|
package/package.json
CHANGED
|
@@ -56,7 +56,7 @@ describe("RenderStateRoot", () => {
|
|
|
56
56
|
expect(values[1]).toEqual(RenderState.Standard);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
it("should not allow nesting of <RenderStateRoot>", () => {
|
|
59
|
+
it("should not allow nesting of <RenderStateRoot> when", () => {
|
|
60
60
|
// Act
|
|
61
61
|
const underTest = () =>
|
|
62
62
|
render(
|
|
@@ -69,4 +69,23 @@ describe("RenderStateRoot", () => {
|
|
|
69
69
|
`"There's already a <RenderStateRoot> above this instance in the render tree. This instance should be removed."`,
|
|
70
70
|
);
|
|
71
71
|
});
|
|
72
|
+
|
|
73
|
+
it("should allow nesting of <RenderStateRoot> when throwIfNested={false}", () => {
|
|
74
|
+
// Act
|
|
75
|
+
const underTest = () =>
|
|
76
|
+
render(
|
|
77
|
+
<RenderStateRoot throwIfNested={false}>
|
|
78
|
+
<RenderStateRoot throwIfNested={false}>
|
|
79
|
+
Hello, world!
|
|
80
|
+
</RenderStateRoot>
|
|
81
|
+
</RenderStateRoot>,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
expect(underTest).not.toThrowError();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// This test can be written once ADR #526 has been implemented. I've left
|
|
88
|
+
// a comment in the ADR about this kind of test case being something we
|
|
89
|
+
// should support.
|
|
90
|
+
it.todo("should only render a single context provider when nesting");
|
|
72
91
|
});
|
|
@@ -11,23 +11,35 @@ const {useContext, useEffect, useState} = React;
|
|
|
11
11
|
|
|
12
12
|
type Props = {|
|
|
13
13
|
children: React.Node,
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Whether the component should throw when nested. Defaults to `true`.
|
|
17
|
+
*/
|
|
18
|
+
throwIfNested?: boolean,
|
|
14
19
|
|};
|
|
15
20
|
|
|
16
|
-
export const RenderStateRoot = ({
|
|
21
|
+
export const RenderStateRoot = ({
|
|
22
|
+
children,
|
|
23
|
+
throwIfNested,
|
|
24
|
+
}: Props): React.Node => {
|
|
17
25
|
const [firstRender, setFirstRender] = useState<boolean>(true);
|
|
18
26
|
const contextValue = useContext(RenderStateContext);
|
|
19
|
-
|
|
20
|
-
if (contextValue !== RenderState.Root) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
"There's already a <RenderStateRoot> above this instance in " +
|
|
23
|
-
"the render tree. This instance should be removed.",
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
27
|
useEffect(() => {
|
|
28
28
|
setFirstRender(false);
|
|
29
29
|
}, []); // This effect will only run once.
|
|
30
30
|
|
|
31
|
+
if (contextValue !== RenderState.Root) {
|
|
32
|
+
if (throwIfNested) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
"There's already a <RenderStateRoot> above this instance in " +
|
|
35
|
+
"the render tree. This instance should be removed.",
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
// Avoid rendering multiple providers if this RenderStateRoot
|
|
39
|
+
// is nested inside another one.
|
|
40
|
+
return children;
|
|
41
|
+
}
|
|
42
|
+
|
|
31
43
|
const value = firstRender ? RenderState.Initial : RenderState.Standard;
|
|
32
44
|
|
|
33
45
|
return (
|
|
@@ -36,3 +48,7 @@ export const RenderStateRoot = ({children}: Props): React.Node => {
|
|
|
36
48
|
</RenderStateContext.Provider>
|
|
37
49
|
);
|
|
38
50
|
};
|
|
51
|
+
|
|
52
|
+
RenderStateRoot.defaultProps = {
|
|
53
|
+
throwIfNested: true,
|
|
54
|
+
};
|