创建一个抽象逻辑的组件(从现有代码中提取)

时间:2019-03-30 09:59:13

标签: reactjs scroll components refactoring

我创建以下代码:

import React from 'react'
import { range } from 'lodash'

const DIV_NUMBER = 5

export default class App extends React.Component {
  constructor(props) {
    super(props)
    this.divs = []
  }

  handleScroll = divIdx => () => {
    const divRef = this.divs[divIdx]
    const left = divRef.scrollLeft
    const top = divRef.scrollTop
    this.divs.forEach(div => (div.scrollLeft = left))
    this.divs.forEach(div => (div.scrollTop = top))
  }

  render() {
    return (
      <div style={{ border: '1px solid tomato' }}>
        {range(DIV_NUMBER).map(i => {
          return (
            <div
              key={i}
              ref={divElem => (this.divs[i] = divElem)}
              onScroll={this.handleScroll(i)}
              style={{
                width: 300,
                height: 100,
                margin: '2px',
                overflow: 'auto',
                border: '1px solid black',
              }}
            >
              <div
                style={{
                  width: 500,
                  height: 400,
                }}
              >
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua. Scelerisque eu ultrices vitae auctor eu
                augue ut lectus. In fermentum et sollicitudin ac orci. Velit sed ullamcorper morbi
                tincidunt ornare. Auctor eu augue ut lectus arcu bibendum. Non nisi est sit amet.
                Facilisis magna etiam tempor orci eu lobortis. Et tortor at risus viverra adipiscing
                at in tellus integer. Lacus luctus accumsan tortor posuere ac ut consequat semper
                viverra. Fermentum dui faucibus in ornare quam viverra orci sagittis. Porttitor eget
                dolor morbi non. Pulvinar pellentesque habitant morbi tristique senectus et.
                Tincidunt eget nullam non nisi est sit amet facilisis magna. Purus semper eget duis
                at tellus at urna condimentum. Ipsum dolor sit amet consectetur adipiscing. Sit amet
                aliquam id diam maecenas ultricies mi eget mauris. Faucibus scelerisque eleifend
                donec pretium vulputate sapien nec sagittis. Tristique senectus et netus et
                malesuada fames ac turpis. Egestas integer eget aliquet nibh. Enim ut tellus
                elementum sagittis vitae. Urna condimentum mattis pellentesque id nibh tortor id
                aliquet. Magna eget est lorem ipsum dolor. Felis imperdiet proin fermentum leo vel
                orci porta. Eget egestas purus viverra accumsan in nisl nisi. Adipiscing commodo
                elit at imperdiet. Facilisis magna etiam tempor orci eu lobortis. Volutpat est velit
                egestas dui id ornare arcu odio. Praesent elementum facilisis leo vel fringilla.
                Laoreet non curabitur gravida arcu ac tortor dignissim convallis aenean. Sodales ut
                etiam sit amet nisl. Turpis massa tincidunt dui ut ornare. Viverra mauris in aliquam
                sem fringilla ut morbi tincidunt augue.
              </div>
            </div>
          )
        })}
      </div>
    )
  }
}

有效。 它创建5个div元素,滚动其中一个元素,所有div滚动滚动条。我使用React引用来做到这一点。

我现在想做的是创建一个抽象该逻辑的组件。

我想像这样的东西:

<ScrollDivs>
  {range(DIV_NUMBER).map(i => {
    return (
      <div
        key={i}
        style={{
          width: 500,
          height: 400,
        }}
      >
        all the text...
      </div>
    )
  })}
</ScrollDivs>

因此,一个神奇的组件ScrollDivs处理逻辑。 谁在使用此组件,不必担心它是如何完成的,他只需要包装希望能够在该组件内一起滚动的div。

我该怎么办?我不知道从哪里开始。

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

React.Children.map可以帮助您遍历props.children,而React.cloneElement可以帮助将新道具传递给孩子:

export default class ScrollDivsSync extends React.Component {
  divs = [];

  handleScroll = e => {
    const { scrollTop, scrollLeft } = e.target;
    this.divs.forEach(div => {
      div.scrollLeft = scrollLeft;
      div.scrollTop = scrollTop;
    });
  };

  render() {
    const { children } = this.props;

    let i = 0;
    const enhancedChildren = React.Children.map(children, child =>
      React.cloneElement(child, {
        onScroll: this.handleScroll,
        ref: divElem => (this.divs[i++] = divElem)
      })
    );

    return enhancedChildren;
  }
}

这是一个带有the example

的CodeSandbox