代码之家  ›  专栏  ›  技术社区  ›  Summer Developer

React JS Context API-窗口滚动事件

  •  2
  • Summer Developer  · 技术社区  · 6 年前

    我已经看过了我认为可能是两个过时的答案,给出了react 16的上下文api。

    他们是:

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

    以及:

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

    我还没反应过来,所以我想知道 Context API ,是在react中执行angular.js类型服务的正确方法(因此我没有 window.addEventListener("scroll") 在监听scroll事件的每个组件上,利用上下文api(在那里创建事件监听器?)只是想知道我是不是在正确的轨道上…

    它讨论的是能够传递道具,以及嵌套组件能够更改状态,让包装组件收集滚动位置、更新上下文(滚动位置)并将其传递给所需的元素是错误的吗?有推荐的方法吗?有多种 window.addEventListener(“滚动”) 哪怕是个问题?

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

    因此,我不确定是否要从顶级/父元素更新上下文并将其传递给内部组件。

    1 回复  |  直到 6 年前
        1
  •  9
  •   Ori Drori    6 年前

    你可以使用 context 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>