I've looked at what I believe may be two outdated answers given React 16's Context API.
They are:
React.js best practice regarding listening to window events from ponents
And:
How to implement service(concept in AngularJS) -like ponent in React
I'm fairly new to React, so I was wondering, given the Context API, is the correct way to do an Angular.js type of service in React (so I don't have window.addEventListener("scroll")
on every ponent that is listening to the scroll event, to leverage the Context API (create the event listener there?). Just wondering if I'm on the right track here...
It talks about being able to pass down props, and also about nested ponents being able to change the state, would it be wrong to have a wrapper ponent collecting the scroll position, updating the Context (scroll position), and passing that down to the needed elements? Is there a remended way to do this and are multiple window.addEventListener("scroll")
even a problem?
I was having trouble understanding how to update the context from a nested ponent once it was created - in the docs here: .html#updating-context-from-a-nested-ponent
So I'm not sure about updating context from a top-level/parent element and passing it down to the interior ponents.
I've looked at what I believe may be two outdated answers given React 16's Context API.
They are:
React.js best practice regarding listening to window events from ponents
And:
How to implement service(concept in AngularJS) -like ponent in React
I'm fairly new to React, so I was wondering, given the Context API, is the correct way to do an Angular.js type of service in React (so I don't have window.addEventListener("scroll")
on every ponent that is listening to the scroll event, to leverage the Context API (create the event listener there?). Just wondering if I'm on the right track here...
It talks about being able to pass down props, and also about nested ponents being able to change the state, would it be wrong to have a wrapper ponent collecting the scroll position, updating the Context (scroll position), and passing that down to the needed elements? Is there a remended way to do this and are multiple window.addEventListener("scroll")
even a problem?
I was having trouble understanding how to update the context from a nested ponent once it was created - in the docs here: https://reactjs/docs/context.html#updating-context-from-a-nested-ponent
So I'm not sure about updating context from a top-level/parent element and passing it down to the interior ponents.
Share Improve this question asked Jul 20, 2018 at 20:01 Summer DeveloperSummer Developer 2,0868 gold badges35 silver badges68 bronze badges1 Answer
Reset to default 12You can use the context API to create a Provider with a HoC. Whenever the window size changes, the provider notify's the consumer by updating the width/height, and the consumer in the HoC, rerenders the ponents.
Example:
const getDimensions = () => ({
width: window.innerWidth,
height: window.innerHeight
});
const ResizeContext = React.createContext(getDimensions());
class ResizeProvider extends React.PureComponent {
state = getDimensions();
// you might want to debounce or throttle the event listener
eventListener = () => this.setState(getDimensions());
ponentDidMount() {
window.addEventListener('resize', this.eventListener);
}
ponentWillUnmount() {
window.removeEventListener('resize', this.eventListener);
}
render() {
return (
<ResizeContext.Provider value={this.state}>
{
this.props.children
}
</ResizeContext.Provider>
);
}
}
const withResize = (Component) => (props) => (
<ResizeContext.Consumer>
{({ width, height }) => (
<Component {...props} width={width} height={height} />
)}
</ResizeContext.Consumer>
);
const ShowSize = withResize(({ width, height }) => (
<div>
<div>Width: {width}</div>
<div>Height: {height}</div>
</div>
));
const Demo = () => (
<ResizeProvider>
<ShowSize />
</ResizeProvider>
);
ReactDOM.render(
<Demo />,
demo
);
<script crossorigin src="https://unpkg./react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg./react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>