Skip to content
3 changes: 3 additions & 0 deletions lib/src/builder/generation/impl_generation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ class ImplGenerator {
..writeln()
..writeln(' @override')
..writeln(' set state(Map value) {')
..writeln(' assert(value is JsBackedMap, ')
..writeln(' \'Component2.state should only be set via \'')
..writeln(' \'initializeState (within the init lifecycle method) or setState.\');')
..writeln(' super.state = value;')
..writeln(' _cachedTypedState = typedStateFactoryJs(value);')
..writeln(' }')
Expand Down
4 changes: 4 additions & 0 deletions lib/src/component/error_boundary.over_react.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions lib/src/component/error_boundary_mixins.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ abstract class _$ErrorBoundaryStateMixin implements UiState {
/// }
mixin ErrorBoundaryMixin<T extends ErrorBoundaryPropsMixin, S extends ErrorBoundaryStateMixin>
on UiStatefulComponent2<T, S> {
// TODO (CPLAT-5816): Convert this to use `init` once the generated setter doesn't cause an RTE
@mustCallSuper
@override
Map getInitialState() => newState()..hasError = false;
void init() {
initializeState(newState()..hasError = false);
}

@mustCallSuper
@override
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:html';

import 'package:over_react/over_react.dart';
import 'package:over_react/react_dom.dart' as react_dom;
import 'package:test/test.dart';

import '../../../../test_util/test_util.dart';
Expand All @@ -26,6 +29,13 @@ main() {
}, throwsA(const TypeMatcher<IllegalInstantiationError>()));
});

test('component cannot set state directly in init', () {
expect(() => render((StatefulComponentTest()..setStateDirectly = true)()),
throwsA(hasToStringValue('Assertion failed: "Component2.state should '
'only be set via initializeState (within the init lifecycle method) '
'or setState."')));
}, testOn: '!js');

test('renders a component from end to end, successfully reading state via typed getters', () {
var renderedInstance = render(StatefulComponentTest()());
expect(renderedInstance, isNotNull);
Expand Down Expand Up @@ -82,7 +92,10 @@ main() {
UiFactory<StatefulComponentTestProps> StatefulComponentTest = _$StatefulComponentTest;

@Props()
class _$StatefulComponentTestProps extends UiProps {}
class _$StatefulComponentTestProps extends UiProps {
/// Used to test if a component has the capability to set state via this.setState.
bool setStateDirectly;
}

@State()
class _$StatefulComponentTestState extends UiState {
Expand All @@ -103,14 +116,23 @@ class _$StatefulComponentTestState extends UiState {
@Component2()
class StatefulComponentTestComponent extends UiStatefulComponent2<StatefulComponentTestProps, StatefulComponentTestState> {
@override
getInitialState() => (newState()
..stringState = '1'
..dynamicState = '2'
..untypedState = '3'
..customKeyState = '4'
..customNamespaceState = '5'
..customKeyAndNamespaceState = '6'
);
Map getDefaultProps() => newProps()..setStateDirectly = false;

@override
void init() {
if (this.props.setStateDirectly) {
this.state = newState()
..stringState = '1';
} else {
this.initializeState(newState()
..stringState = '1'
..dynamicState = '2'
..untypedState = '3'
..customKeyState = '4'
..customNamespaceState = '5'
..customKeyAndNamespaceState = '6');
}
}

@override
render() => (Dom.div()
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions web/component2/src/demo_components/button.over_react.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions web/component2/src/demo_components/progress.over_react.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.