针对this.props.children的特定孩子

时间:2016-03-29 17:07:12

标签: javascript reactjs

我有一个<Panel />组件,结构如下:

import React, {Component, PropTypes} from 'react';

export default class Panel extends Component {

    static propTypes = {
        children: PropTypes.object,
        scrollable: PropTypes.bool,
        swipeable: PropTypes.bool
    };

    static defaultProps = {
        scrollable: true,
        swipeable: false
    };

    render() {
        const styles = require('./Panel.css');

        const {
            children,
            scrollable
        } = this.props;

        return (
            <div className={styles.Base}>
                { scrollable ?
                    <div className={styles.ScrollArea}>{children}</div>
                    : {children}
                }
            </div>
        );
    }
}

它基本上只是一个包装器组件,通常包含一个可滚动项列表。我这样用它:

<Panel>
    <ul className={styles.FontMenu}>
        { fonts.map((font) => {
            return (
                <li
                    key={`font-menu-${font.id}`}
                    className={selectedFamily.id === font.id ? styles['FontMenuItem--isActive'] : styles.FontMenuItem}>
                    {font.label}
                </li>
            );
        })}
    </ul>
</Panel>

我偶尔需要能够在面板安装时滚动到列表中的特定项目。我知道我要滚动到的项目的索引,并且我想向<Panel />组件添加一个方法,该方法使用该索引将scrollTo prop作为属性,但是列表中的项目是动态的孩子我不确定什么可能是一种聪明的实施方式。

如何轻松定位组件的动态子级并获取其属性?

2 个答案:

答案 0 :(得分:0)

我不确定如何实现问题的解决方案,因为我无法分辨如何设置scrollTo。如果它是基于子属性设置的,那么您可能希望在Panel的render()中使用cloneElement在子项上设置自定义属性:

render(){
 return (
   <div>
     {this.renderChildren()}
   </div>
   
   )
  
}

renderChildren(){
  return React.Children.map(this.props.children, function(child){
    if (child.property1 === 'scrollHere'){
      return React.cloneElement(child, { shouldScrollToHere: true })
      else return child
    }.bind(this))
  } 

然后在Panel的componentDidMount()中,也许您可​​以查看子项并使用setState滚动到正确的项目。

答案 1 :(得分:0)

一种方法可能是定义一个包含给定子组件的单独的高阶组件,允许您传入一个焦点道具,指示是否要聚焦给定组件:

import React, { PropTypes } from 'react'

var FocusWrapper = function(Component) {
    return (props) => (
        <Component {...props} ref={(c) => {
            if (props.focus) {
                c.focus()
            }
        }}
    )
}

FocusWrapper.PropTypes = {
    focus: PropTypes.bool
}

然后你可以根据它的props包装任何需要焦点方法的组件,并使用主组件中的包装组件。