警告:包裹外部组件时,“未知道具”

时间:2019-03-15 09:39:30

标签: javascript reactjs

我将hoc组件包装到另一个组件,但显示警告 警告是warning.js?6327:33警告:标签上的未知道具scrollElementIntoViewscrollIntoView。从元素中删除这些道具。

enter image description here

这是我的特殊组件:

import React from 'react';
import ReactDOM from 'react-dom';
import scrollIntoViewExternal from 'scroll-into-view';
import _ from 'lodash';

export default function ScrollingHOC(WrappedComponent) {
    return class extends React.Component {
        constructor(props) {
            super(props);
            this.scrollIntoView = this.scrollIntoView.bind(this);
            this.scrollElementIntoView = this.scrollElementIntoView.bind(this);
        }

        scrollIntoView(options = {}) {
            this.scrollElementIntoView(ReactDOM.findDOMNode(this), options);

            /*
            options {
                animationTime: 500, // (optional) integer, time in milliseconds
                topOffset: 0, // (optional) integer, pixels to offset top alignment
                callbackFinished: function(result) {}, // (optional) function, result parameter is currently 'cancelled' or 'completed'
            }
            */
        }

        scrollElementIntoView(element, options = {}) {
            let domElement = false;
            if (_.isElement(element)) {
                // is already a DOM element
                domElement = element;
                if (__DEBUG__) {
                    console.log(
                        `scrolling DOM element with a height of ${
                            domElement.scrollHeight
                            }`
                    );
                }
            } else if (_.get(element, 'props', false) !== false) {
                // await a mounted react element or component
                // TODO: improve test, 'props' is only a weak check, findDOMNode still can fail
                domElement = ReactDOM.findDOMNode(element);
                if (__DEBUG__) {
                    console.log(
                        `scrolling react element with a height of ${
                            domElement.scrollHeight
                            }`
                    );
                }
            }

            if (!domElement) {
                if (__DEBUG__) {
                    console.warn(
                        'Cannot scroll element that is not part of the DOM.'
                    );
                }
                return false;
            }

            return scrollIntoViewExternal(
                domElement,
                {
                    time: _.get(options, 'animationTime', 500),
                    align: {
                        top: 0, // align it to the top, or user cannot see top part if element is higher than the viewport
                        topOffset: _.get(options, 'topOffset', 0),
                    },
                    /*
                        We replace the standard isScrollable with a function which also checks
                        overflowX and overflowY, as only checking overflow is not enough in IE/Edge,
                        because if the following is set:
                        .foo {
                            overflow-x: hidden;
                            overflow-y: auto;
                        }
                        `getComputedStyle(element).overflow` will yield `'hidden'`
                     */
                    isScrollable(el) {
                        if (el === window) {
                            return true;
                        }

                        if (
                            el.scrollHeight !== el.clientHeight ||
                            el.scrollWidth !== el.clientWidth
                        ) {
                            const css = getComputedStyle(el);

                            return (
                                css &&
                                (css.overflow !== 'hidden' ||
                                    (_.get(options, 'scrollY', true) &&
                                        css.overflowY !== 'hidden') ||
                                    (_.get(options, 'scrollX', true) &&
                                        css.overflowX !== 'hidden'))
                            );
                        }
                        return false;
                    },
                },
                result => {
                    if (__DEBUG__) {
                        console.log(
                            `element scrolling ${result}, now at ${
                                domElement.getBoundingClientRect().top
                                }`
                        );
                    }

                    if (_.isFunction(options.callbackFinished)) {
                        options.callbackFinished(result);
                    }
                }
            );
        }

    render() {
            return (<WrappedComponent scrollElementIntoView={this.scrollElementIntoView} scrollIntoView={this.scrollIntoView} {...this.props}/>)
        }
    }
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.1/react-dom.min.js"></script>

我的组件在这里:

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import ReactMDLCard from 'react-mdl/lib/Card/Card';
import ScrollingHOC from '../../hocs/ScrollingHOC';


const Card = props => {
    const {
        className,
        stretch,
        shadow,
        fixedActions,
        reducedSize,
        children,
        ...otherProps
    } = props;

    const classes = classNames(
        {
            'mdl-card--stretch': stretch === true,
            'mdl-card--has-fixed-actions': fixedActions === true,
            'mdl-card--reduced': reducedSize === true,
        },
        className
    );

    return (
        <ReactMDLCard
            className={classes}
            shadow={shadow > 0 ? shadow - 1 : undefined}
            {...otherProps}>
            {children}
        </ReactMDLCard>
    );

};
// define property types
Card.propTypes = {
    className: PropTypes.string,
    shadow: PropTypes.number,
    stretch: PropTypes.bool,
    fixedActions: PropTypes.bool,
    reducedSize: PropTypes.bool,
};
Card.defaultProps = {
    shadow: 1,
    stretch: true,
    fixedActions: false,
    reducedSize: false,
};

Card.displayName = 'Card';

export default ScrollingHOC(Card);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.1/react-dom.min.js"></script>

2 个答案:

答案 0 :(得分:0)

为什么首先要传递scrollElementIntoView作为prop(我看不到使用它)?我相信,当您使用HOC封装组件,并且组件渲染具有<div> ... </div>作为第一个元素时,此div会获得支持,这是不应该发生的。

答案 1 :(得分:0)

您正在将scrollElementIntoViewscrollIntoView下传到<ReactMDLCard />

  1. 您可以在
  2. 中对其进行破坏
 const {
        /*..*/
        scrollElementIntoView
        scrollIntoView 
        ...otherProps
    } = props;
  1. 第二种选择是从props对象中忽略它们-使用omit中的lodash在组件中执行类似...(_.omit(otherProps, ['scrollElementIntoView', 'scrollIntoView']))的操作
        <ReactMDLCard
            className={classes}
            shadow={shadow > 0 ? shadow - 1 : undefined}
            {...(_.omit(otherProps, ['scrollElementIntoView', 'scrollIntoView']))}
            {children}
        </ReactMDLCard>