Skip to content

Commit

Permalink
Add docs around connect and late props, migration info for connect an…
Browse files Browse the repository at this point in the history
…d wrappers
  • Loading branch information
greglittlefield-wf committed Sep 20, 2024
1 parent 7222cd1 commit 7e7dda5
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
23 changes: 23 additions & 0 deletions doc/null_safety/null_safe_migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ Run the null safety migrator tool:
Below are some common cases that might come up while running the migrator tool on a repo using over_react.
* [Prop requiredness and nullability](#prop-requiredness-and-nullability)
* [Wrapper and `connect`ed components and required props](#wrapper-and-connected-components-and-required-props)
* [Implementing abstract `Ref`s](#implementing-abstract-refs)
* [Incorrect `getDerivedStateFromProps` Return Signature](#incorrect-getderivedstatefromprops-return-signature)
* [Verbose function component return signature for `uiForwardRef`](#verbose-function-component-return-signature-for-uiforwardref)
* [Nullable store/actions generics on `FluxUiPropsMixin`](#nullable-storeactions-generics-on-fluxuipropsmixin)
* [Nullable props generic on `UiComponent2` mixins](#nullable-props-generic-on-uicomponent2-mixins)

#### Prop requiredness and nullability

First, check out our documentation around [null safety and required props](../null_safety_and_required_props.md).
Expand Down Expand Up @@ -188,6 +196,21 @@ flowchart TD
End_Required[/"Make it <strong>required</strong>\n<code>late SomeType propName;</code>"\]
```

### Wrapper and `connect`ed components and required props

There may be some cases where you have a wrapper component or `connect`ed component that sets some required props,
but you get lints and runtime errors about missing props when consuming them.

See [this section](../null_safety_and_required_props.md#disabling-required-prop-validation-for-certain-props)
of the null safety and required props docs for instructions on how to handle these cases and suppress this validation.

#### connect

We'll be adding a codemod to help migrate the `connect` case: https://github.com/Workiva/over_react_codemod/issues/295

Alternatively, you could refactor your component to instead utilize [OverReact Redux hooks](./over_react_redux_documentation.md#hooks),
which avoid this problem by accessing store data and dispatchers directly in the component as opposed to passing it in via props.

#### Implementing abstract `Ref`s

After migrating to null-safety, it may be necessary to add left side typing on `Ref`s when overriding abstract getters as shown in the example below:
Expand Down
37 changes: 36 additions & 1 deletion doc/null_safety_and_required_props.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,9 @@ This mechanism does not apply to function components, which use a different prop

Sometimes, you want to declare a prop as non-nullable and required, but not enforce that consumers explicitly set it.

There are two ways to opt out of prop validation for certain props, targeted toward to main use-cases:
There are two ways to opt out of prop validation for certain props, targeted toward these main use-cases:
- [wrapper components](#disabling-validation-use-case-wrapper-components)
- [connect](#disabling-validation-use-case-connect)
- [cloned props](#disabling-validation-use-case-cloned-props)

#### Disabling validation use-case: wrapper components
Expand Down Expand Up @@ -180,6 +181,40 @@ class WrapperProps = UiProps with FooProps, WrapperPropsMixin;
> See the [unsafe required prop reads](#unsafe-required-prop-reads) section for more info

#### Disabling validation use-case: `connect`
Similar to [the wrapper component case](#disabling-validation-use-case-wrapper-components) in the previous section,
we'll want to disable validation similarly using `@Props(disableRequiredPropValidation: {...})`
for any late required props assigned within connect.

For example:
```dart
mixin CounterPropsMixin on UiProps {
// Set in connect.
late int count;
late void Function() increment;
// Must be set by consumers of the connected compoennt.
late String requiredByConsumer;
}
@Props(disableRequiredPropValidation: {'count', 'increment'})
class CounterProps = UiProps with CounterPropsMixin, OtherPropsMixin;
UiFactory<CounterProps> Counter = connect<CounterState, CounterProps>(
mapStateToProps: (state) => (Counter()
..count = state.count
),
mapDispatchToProps: (dispatch) => (Counter()
..increment = (() => dispatch(IncrementAction()))
),
)(_$Counter);
example() => (Counter()..requiredByConsumer = 'foo')();
```

Note that [OverReact Redux hooks](./over_react_redux_documentation.md#hooks)
avoid this problem by accessing store data and dispatchers directly in the component as opposed to passing it in via props.

#### Disabling validation use-case: cloned props

Sometimes, you want to declare a prop that's always cloned onto it by a parent component.
Expand Down
18 changes: 18 additions & 0 deletions doc/over_react_redux_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,24 @@ UiFactory<CounterProps> Counter = connect<CounterState, CounterProps>(
)(_$Counter);
```

Note that any required props assigned in connect must have their validation disabled; see docs [here](./null_safety_and_required_props.md#disabling-validation-use-case-connect)
for more info.

For example:
```dart
mixin CounterPropsMixin on UiProps {
// Set in connect.
late int count;
late void Function() increment;
// Must be set by consumers of the connected compoennt.
late String requiredByConsumer;
}
@Props(disableRequiredPropValidation: {'count', 'increment'})
class CounterProps = UiProps with CounterPropsMixin, OtherPropsMixin;
```

### `connect` Parameters

- #### `mapStateToProps`
Expand Down

0 comments on commit 7e7dda5

Please sign in to comment.