React-从父级引用子级组件

时间:2019-02-20 09:23:33

标签: reactjs

概述:
布局示例:
A B C D E F
G H I J

我有一个项目网格(A,B,C,D,E,F)。单击一个项目(C)时,在(G,H,I,J)下面显示子项目列表。为了使在进行制表时可以访问此选项,一旦单击了某个项目,焦点就会移到子项目列表中。但是,一旦所有这些项目都被选中,我想集中精力转到下一个主要项目(D)。

问题:
我正在向A,B,C,D,E和F添加引用,但似乎无法访问网格中的引用来更新焦点。

//项目

constructor(props) {
    super(props);
    this.ref = React.createRef();
}
getItemRef() {
    return this.ref;
}
render() {
    return (
        <a ref={this.ref}>Stuff</a>
    );
}

//父母

renderItems() {
    return (
        <React.Fragment>
            <Item>
            <Item>
            <Item>
        </React.Fragment>
    );
}
render() {
    return (
        <Grid>
            {this.renderItems()}
        </Grid>
    );
}

//网格

componentWillReceiveProps(nextProps) {
    React.Children.forEach(this.props.children, function(child) {
        console.log(typeof child.getItemRef === 'function'); // always false
    });
}

1 个答案:

答案 0 :(得分:0)

child是React元素对象,而不是组件实例。为了访问组件实例,父组件应使用引用并提供对项目的引用。

如果子计数不变,则refs数组的长度可以固定。

网格组件:

itemRefs = [...Array(React.Children(this.props.children).count)].map(() => React.createRef);

render() {
  return React.Children.map(this.props.children, ((item, i) => 
    React.cloneElement(child, { ref: this.itemRefs[i] });
  )
}

父组件:

render() {
    return (
        <Grid>
            <Item>
            <Item>
            <Item>
        </Grid>
    );
}

请注意,父组件有望提供<Item>作为<Grid>子代,而没有<Fragment>包装器。

如果期望Grid使用嵌套的<a>做某事,那么依靠孙子引用不是一个好习惯,Item应该提供公共API来访问它(焦点,模糊等),而ref属性保持私有状态。