Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
335 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import PropTypes from 'prop-types'; | ||
import React, { useRef } from 'react'; | ||
|
||
import Typography from '@material-ui/core/Typography'; | ||
|
||
interface RenderCountProps { | ||
prefix?: string; | ||
} | ||
|
||
const RenderCount: React.FC<RenderCountProps> = (props) => { | ||
const { prefix = 'Render count: ' } = props; | ||
|
||
const renderCountRef = useRef(0); | ||
renderCountRef.current++; | ||
|
||
return ( | ||
<Typography variant="body1"> | ||
{prefix} | ||
{renderCountRef.current} | ||
</Typography> | ||
); | ||
}; | ||
|
||
RenderCount.propTypes = { | ||
prefix: PropTypes.string, | ||
}; | ||
|
||
export default RenderCount; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
export { default as reduxDecorator } from './reduxDecorator'; | ||
export * from './reduxDecorator'; | ||
|
||
export { default as useCountSelector } from './useCountSelector'; | ||
export * from './useCountSelector'; | ||
|
||
export * from './store'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { useSelector } from 'react-redux'; | ||
|
||
import { DevHelperState } from './store'; | ||
|
||
const countSelector = (state: DevHelperState) => state.count; | ||
|
||
const useCountSelector = (): number => { | ||
return useSelector(countSelector); | ||
}; | ||
|
||
export default useCountSelector; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 35 additions & 36 deletions
71
packages/react-pauseable-containers/src/PauseableReduxContainer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,43 @@ | ||
import React, { PropsWithChildren, ReactElement } from 'react'; | ||
import { Store } from 'redux'; | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { Provider, useStore } from 'react-redux'; | ||
|
||
import { createPauseableStore, PauseableStoreInstance } from 'redux-pauseable-store'; | ||
|
||
import { PauseableContainerProps } from './types'; | ||
|
||
const PauseableReduxContainer: React.FC<PauseableContainerProps> = ({ | ||
shouldUpdate, | ||
children, | ||
}: PropsWithChildren<PauseableContainerProps>): ReactElement | null => { | ||
const store = useStore(); | ||
const staticStoreRef = React.useRef<Store>(); | ||
const wasActiveRef = React.useRef<boolean>(); | ||
|
||
const stateWhenLastActive = React.useRef<Store>(); | ||
|
||
if (shouldUpdate) { | ||
// Track stuff for when we go inactive | ||
stateWhenLastActive.current = store.getState(); | ||
} else { | ||
if (wasActiveRef.current) { | ||
// We're going inactive: freeze the store contents to the last-active state | ||
staticStoreRef.current = { | ||
...store, | ||
getState: (): ReturnType<typeof store.getState> => stateWhenLastActive.current, | ||
}; | ||
} else { | ||
// We're somehow being rendered in an initially-inactive state: that can't be right | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.warn( | ||
'PauseableReduxContainer is being mounted with shouldUpdate=false: this is probably a bug', | ||
); | ||
} | ||
return null; | ||
} | ||
} | ||
|
||
wasActiveRef.current = shouldUpdate; | ||
return ( | ||
<Provider store={shouldUpdate ? store : (staticStoreRef.current as Store)}>{children}</Provider> | ||
export interface PauseableReduxContainerProps extends PauseableContainerProps { | ||
children: React.ReactNode; | ||
dispatchWhenPaused?: boolean | null; | ||
} | ||
|
||
const PauseableReduxContainer: React.FC<PauseableReduxContainerProps> = (props) => { | ||
const { dispatchWhenPaused, shouldUpdate, children } = props; | ||
|
||
const parentStore = useStore(); | ||
const pauseableStore = React.useMemo<PauseableStoreInstance>( | ||
() => | ||
createPauseableStore(parentStore, { | ||
// A change to the `shouldUpdate` prop will already cause a rerender, so we don't need an extra notification | ||
notifyListersOnUnpause: false, | ||
}), | ||
[parentStore], | ||
); | ||
|
||
pauseableStore.setPaused(!shouldUpdate); | ||
pauseableStore.setDispatch(dispatchWhenPaused); | ||
|
||
return <Provider store={pauseableStore}>{children}</Provider>; | ||
}; | ||
|
||
PauseableReduxContainer.defaultProps = { | ||
dispatchWhenPaused: null, | ||
}; | ||
|
||
PauseableReduxContainer.propTypes = { | ||
children: PropTypes.node.isRequired, | ||
dispatchWhenPaused: PropTypes.bool, | ||
shouldUpdate: PropTypes.bool.isRequired, | ||
}; | ||
|
||
export default PauseableReduxContainer; |
50 changes: 50 additions & 0 deletions
50
packages/react-pauseable-containers/stories/PauseableComponentItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import PropTypes from 'prop-types'; | ||
import React, { useState } from 'react'; | ||
|
||
import Checkbox from '@material-ui/core/Checkbox'; | ||
import Chip from '@material-ui/core/Chip'; | ||
import FormControlLabel from '@material-ui/core/FormControlLabel'; | ||
import Paper from '@material-ui/core/Paper'; | ||
import Typography from '@material-ui/core/Typography'; | ||
|
||
import { RenderCount } from 'react-hibernate-dev-helpers'; | ||
|
||
import { PauseableComponentContainer } from '../src'; | ||
|
||
export interface PauseableComponentItemProps { | ||
count: number; | ||
} | ||
|
||
const PauseableComponentItem: React.FC<PauseableComponentItemProps> = (props) => { | ||
const { count } = props; | ||
|
||
const [shouldUpdate, setShouldUpdate] = useState(true); | ||
|
||
return ( | ||
<Paper style={{ marginTop: 10, padding: 5 }}> | ||
<FormControlLabel | ||
control={ | ||
<Checkbox | ||
checked={shouldUpdate} | ||
onChange={(event) => setShouldUpdate(event.target.checked)} | ||
/> | ||
} | ||
label="shouldUpdate" | ||
/> | ||
<div> | ||
<PauseableComponentContainer shouldUpdate={shouldUpdate}> | ||
<Typography variant="body1" component="div"> | ||
count: <Chip label={count} /> | ||
</Typography> | ||
<RenderCount /> | ||
</PauseableComponentContainer> | ||
</div> | ||
</Paper> | ||
); | ||
}; | ||
|
||
PauseableComponentItem.propTypes = { | ||
count: PropTypes.number.isRequired, | ||
}; | ||
|
||
export default PauseableComponentItem; |
58 changes: 58 additions & 0 deletions
58
packages/react-pauseable-containers/stories/PauseableReduxItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import PropTypes from 'prop-types'; | ||
import React, { useState } from 'react'; | ||
|
||
import Checkbox from '@material-ui/core/Checkbox'; | ||
import Chip from '@material-ui/core/Chip'; | ||
import FormControlLabel from '@material-ui/core/FormControlLabel'; | ||
import Typography from '@material-ui/core/Typography'; | ||
import Paper from '@material-ui/core/Paper'; | ||
|
||
import { RenderCount, useCountSelector } from 'react-hibernate-dev-helpers'; | ||
|
||
import { PauseableComponentContainer, PauseableReduxContainer } from '../src'; | ||
|
||
interface PauseableReduxItemProps { | ||
dispatchWhenPaused?: boolean; | ||
} | ||
|
||
const PauseableReduxItem: React.FC<PauseableReduxItemProps> = (props) => { | ||
const { dispatchWhenPaused } = props; | ||
const count = useCountSelector(); | ||
|
||
const [shouldUpdate, setShouldUpdate] = useState(true); | ||
|
||
return ( | ||
<Paper style={{ marginTop: 10, padding: 5 }}> | ||
<FormControlLabel | ||
control={ | ||
<Checkbox | ||
checked={shouldUpdate} | ||
onChange={(event) => setShouldUpdate(event.target.checked)} | ||
/> | ||
} | ||
label="shouldUpdate" | ||
/> | ||
<PauseableComponentContainer shouldUpdate={shouldUpdate}> | ||
<PauseableReduxContainer | ||
shouldUpdate={shouldUpdate} | ||
dispatchWhenPaused={dispatchWhenPaused} | ||
> | ||
<Typography variant="body1" component="div"> | ||
count: <Chip label={count} /> | ||
</Typography> | ||
<RenderCount /> | ||
</PauseableReduxContainer> | ||
</PauseableComponentContainer> | ||
</Paper> | ||
); | ||
}; | ||
|
||
PauseableReduxItem.propTypes = { | ||
dispatchWhenPaused: PropTypes.bool, | ||
}; | ||
|
||
PauseableReduxItem.defaultProps = { | ||
dispatchWhenPaused: false, | ||
}; | ||
|
||
export default PauseableReduxItem; |
29 changes: 29 additions & 0 deletions
29
packages/react-pauseable-containers/stories/ReduxMonitor.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React, { useCallback } from 'react'; | ||
|
||
import Chip from '@material-ui/core/Chip'; | ||
|
||
import { incrementAction, useCountSelector } from 'react-hibernate-dev-helpers'; | ||
|
||
import Button from '@material-ui/core/Button'; | ||
import { useDispatch } from 'react-redux'; | ||
|
||
const PauseableReduxItem: React.FC = () => { | ||
const dispatch = useDispatch(); | ||
const count = useCountSelector(); | ||
|
||
const increment = useCallback(() => dispatch(incrementAction()), []); | ||
|
||
return ( | ||
<> | ||
<Button onClick={increment} variant="contained"> | ||
Increment | ||
</Button> | ||
<div> | ||
Redux count: | ||
<Chip label={count} /> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default PauseableReduxItem; |
Oops, something went wrong.