我已经研究了我认为在React 16的Context API中可能有两个过时的答案。
它们是:
React.js关于从组件监听窗口事件的最佳实践
和:
如何在React 中实现类似服务(AngularJS中的概念(的组件
我对React相当陌生,所以我想知道,考虑到Context API,在React中使用Angular.js类型的服务的正确方法是什么(所以我没有在每个监听滚动事件的组件上使用window.addEventListener("scroll")
,以利用Context API(在那里创建事件侦听器?(。只是想知道我是否在正确的轨道上。。。
它谈到了能够传递道具,也谈到了嵌套组件能够改变状态,让包装器组件收集滚动位置、更新上下文(滚动位置(并将其传递给所需的元素是错误的吗?有推荐的方法吗?多个window.addEventListener("scroll")
甚至是个问题吗?
我很难理解如何在创建嵌套组件后从中更新上下文——在这里的文档中:https://reactjs.org/docs/context.html#updating-嵌套组件的上下文
因此,我不确定是否要从顶级/父元素更新上下文并将其传递给内部组件。
您可以使用上下文API来创建具有HoC的提供程序。每当窗口大小发生变化时,提供者都会通过更新宽度/高度来通知使用者,而HoC中的使用者会重新发送组件。
示例:
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());
componentDidMount() {
window.addEventListener('resize', this.eventListener);
}
componentWillUnmount() {
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.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>