【问题标题】:React JS Context API - Window Scroll EventsReact JS 上下文 API - 窗口滚动事件
【发布时间】:2018-07-20 20:01:33
【问题描述】:

鉴于 React 16 的 Context API,我查看了我认为可能是两个过时的答案。

他们是:

React.js best practice regarding listening to window events from components

还有:

How to implement service(concept in AngularJS) -like component in React

我对 React 还很陌生,所以我想知道,鉴于 Context API,是在 React 中执行 Angular.js 类型服务的正确方法(所以我没有在每个组件上都有 window.addEventListener("scroll")正在监听滚动事件,以利用 Context API(在那里创建事件监听器?)。只是想知道我是否在正确的轨道上......

它谈到能够传递道具,以及嵌套组件能够改变状态,让包装组件收集滚动位置,更新上下文(滚动位置)并传递它是错误的到需要的元素?有没有推荐的方法来做到这一点,多个window.addEventListener("scroll") 甚至是一个问题?

在嵌套组件创建后,我无法理解如何从嵌套组件更新上下文 - 在此处的文档中:https://reactjs.org/docs/context.html#updating-context-from-a-nested-component

所以我不确定从顶级/父元素更新上下文并将其传递给内部组件。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您可以使用context API 创建一个带有HoC 的Provider。每当窗口大小发生变化时,提供者会通过更新宽度/高度来通知消费者,而 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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 2014-06-01
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多