2019-03-18 19:03:34 +08:00
# Redux framework
2020-01-13 15:03:22 +08:00
Grafana uses [Redux Toolkit ](https://redux-toolkit.js.org/ ) to handle Redux boilerplate code.
2021-09-29 20:34:40 +08:00
2024-08-23 23:08:04 +08:00
> **Note:** Some of our reducers are used by Angular; therefore, consider state to be mutable for those reducers.
2019-03-18 19:03:34 +08:00
2019-11-15 14:30:50 +08:00
## Test functionality
2019-03-18 19:03:34 +08:00
2024-08-23 23:08:04 +08:00
Here's how to test the functioning of your Redux reducers.
2019-03-18 19:03:34 +08:00
### reducerTester
2024-08-23 23:08:04 +08:00
Use the Fluent API framework to simplify the testing of reducers.
2019-03-18 19:03:34 +08:00
2019-11-15 14:30:50 +08:00
#### Usage
2019-03-18 19:03:34 +08:00
2024-08-23 23:08:04 +08:00
Example of `reducerTester` in use:
2019-03-18 19:03:34 +08:00
```typescript
reducerTester()
.givenReducer(someReducer, initialState)
.whenActionIsDispatched(someAction('reducer tests'))
.thenStateShouldEqual({ ...initialState, data: 'reducer tests' });
```
2019-11-15 14:30:50 +08:00
#### Complex usage
2021-09-29 20:34:40 +08:00
2024-08-23 23:08:04 +08:00
Sometimes you encounter a _resulting state_ that contains properties that are hard to compare, such as `Dates` , but you still want to evaluate whether other props in state are correct.
2019-11-15 14:30:50 +08:00
2024-08-23 23:08:04 +08:00
In these cases, you can evaluate individual properties by using `thenStatePredicateShouldEqual` function on `reducerTester` that will return the resulting state. For example:
2019-11-15 14:30:50 +08:00
```typescript
reducerTester()
.givenReducer(someReducer, initialState)
.whenActionIsDispatched(someAction('reducer tests'))
2021-09-29 20:34:40 +08:00
.thenStatePredicateShouldEqual((resultingState) => {
2019-11-15 14:30:50 +08:00
expect(resultingState.data).toEqual('reducer tests');
2021-09-29 20:34:40 +08:00
return true;
2019-11-15 14:30:50 +08:00
});
```
### thunkTester
2024-08-23 23:08:04 +08:00
Here's a Fluent API function that simplifies the testing of thunks.
2019-11-15 14:30:50 +08:00
#### Usage
2024-08-23 23:08:04 +08:00
Example of `thunkTester` in use:
2019-11-15 14:30:50 +08:00
```typescript
2021-09-29 20:34:40 +08:00
const dispatchedActions = await thunkTester(initialState).givenThunk(someThunk).whenThunkIsDispatched(arg1, arg2, arg3);
2019-11-15 14:30:50 +08:00
expect(dispatchedActions).toEqual([someAction('reducer tests')]);
```
2020-12-15 22:27:43 +08:00
## Typing of connected props
2024-08-23 23:08:04 +08:00
It is possible to infer connected props automatically from `mapStateToProps` and `mapDispatchToProps` using a helper type `ConnectedProps` from Redux. For this to work properly, split the `connect` call into two parts like so:
2020-12-15 22:27:43 +08:00
```typescript
2021-09-29 20:34:40 +08:00
import { connect, ConnectedProps } from 'react-redux';
2020-12-15 22:27:43 +08:00
const mapStateToProps = (state: StoreState) => {
return {
location: state.location,
initDone: state.panelEditor.initDone,
uiState: state.panelEditor.ui,
};
};
const mapDispatchToProps = {
updateLocation,
initPanelEditor,
panelEditorCleanUp,
setDiscardChanges,
updatePanelEditorUIState,
updateTimeZoneForSession,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
type Props = OwnProps & ConnectedProps< typeof connector > ;
2021-09-29 20:34:40 +08:00
class PanelEditorUnconnected extends PureComponent< Props > {}
2020-12-15 22:27:43 +08:00
export const PanelEditor = connector(PanelEditorUnconnected);
```
2021-09-29 20:34:40 +08:00
2024-08-23 23:08:04 +08:00
For more examples, refer to the [Redux documentation ](https://react-redux.js.org/using-react-redux/static-typing#inferring-the-connected-props-automatically ).