Skip to content

Export context for hooks support #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ The `layers` prop takes an array of objects that will represent each image (or c

## \<ParallaxProvider>

The `<ParallaxProvider />` component is meant to wrap a top level component in your application and is necessary to provide access though React's context API to the parallax controller. This component should only be used once in you app, for instance in an `<AppContainer />` component that won't be mounted/unmounted during route changes. Like so:
The `<ParallaxProvider />` component is meant to wrap a top level component in your application and is necessary to provide access though React context API to the parallax controller. This component should only be used once in you app, for instance in an `<AppContainer />` component that won't be mounted/unmounted during route changes. Like so:

```jsx
const AppContainer = () => (
Expand Down Expand Up @@ -195,6 +195,19 @@ export withController(MyComponent);

```

Also `parallaxController` is accessible using `useController()` [React hook](https://reactjs.org/docs/hooks-intro.html) in components without writing a class or wrapping them in HOC.

```jsx
import { useController } from 'react-scroll-parallax';

const MyComponent = () => {
const { parallaxController } = useController();
// do stuff with `parallaxController`

return <div />;
};
```

### Available Methods

Access the following methods on `parallaxController` via context:
Expand Down Expand Up @@ -228,9 +241,27 @@ class Image extends Component {
export withController(Image);
```

If your parallax components are stuck and acting weird, this is most likely due to the fact that your page initial scroll was not at the top on load. Here's a possible solution to this problem using `useController()` hook. It can be used in your application top level component or specifically in the part of your application where you are experiencing problems.

```jsx
const ParallaxCache = () => {
const { parallaxController } = useController();

useLayoutEffect(() => {
const handler = () => parallaxController.update();
window.addEventListener('load', handler);
return () => window.removeEventListener('load', handler);
}, [parallaxController]);

return null;
};

// <ParallaxCache /> now can be used anywhere you have problems with cached attributes
```

## Troubleshooting

If you're encountering issues like the parallax element jumping around or becoming stuck, there's a few likely culprits. Since this lib caches important positioning states it's posible for these to be outdated and incorrect. The most likely cause for this type of problem is the result of images loading and increasing the height of an element and/or the page. This can be fixed easily by [updating the cache](#example-usage-of-context). Another likely issue is the CSS positioning applied to the parent or parallax element itself is `fixed`. Fixed positioning parallax elements is currently not supported and may appear to work in some cases but break in others. Avoid using `position: fixed` and instead use `static`, `relative` or `absolute`, which this lib was designed to support. If none of these are relevant and you still have trouble please post an issue with your code or a demo that reproduces the problem.
If you're encountering issues like the parallax element jumping around or becoming stuck, there's a few likely culprits. Since this lib caches important positioning states it's possible for these to be outdated and incorrect. The most likely cause for this type of problem is the result of images loading and increasing the height of an element and/or the page. This can be fixed easily by [updating the cache](#example-usage-of-context). Another likely issue is the CSS positioning applied to the parent or parallax element itself is `fixed`. Fixed positioning parallax elements is currently not supported and may appear to work in some cases but break in others. Avoid using `position: fixed` and instead use `static`, `relative` or `absolute`, which this lib was designed to support. If none of these are relevant and you still have trouble please post an issue with your code or a demo that reproduces the problem.

## Browser Support

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-scroll-parallax",
"version": "2.1.2",
"version": "2.1.3",
"description": "React components to create parallax scroll effects for banners, images or any other DOM elements.",
"repository": {
"type": "git",
Expand Down
14 changes: 14 additions & 0 deletions src/components/useController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useContext } from 'react';
import ParallaxContext from '../helpers/ParallaxContext';

export default () => {
const parallaxController = useContext(ParallaxContext);

if (!parallaxController) {
throw new Error(
'Could not find `react-scroll-parallax` context value. Please ensure the component is wrapped in a <ParallaxProvider>'
);
}

return { parallaxController };
};
8 changes: 8 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,11 @@ type RemoveProps<T, U extends keyof T> = Pick<T, Exclude<keyof T, U>>;
export function withController<P extends WithControllerInjectedProps>(
Component: React.ComponentType<P>
): React.ComponentType<RemoveProps<P, 'parallaxController'>>;

export interface ParallaxContextValue {
parallaxController: ParallaxController;
}

export const ParallaxContext: React.Context<ParallaxContextValue>;

export function useController(): WithControllerInjectedProps;
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// all module exports
export useController from './components/useController';
export withController from './components/withController';
export Parallax from './components/Parallax';
export ParallaxProvider from './components/ParallaxProvider';
export ParallaxBanner from './components/ParallaxBanner';
export ParallaxContext from './helpers/ParallaxContext';