对React Forwarded Refs

时间:2019-11-19 00:09:52

标签: reactjs react-forwardref

我正在尝试使用React转发的引用做一些棘手的事情,有些事情我不太了解。

我正在尝试在React中使用转发引用来创建一组子节点,所有这些都可以通过将转发引用应用于单个javascript对象来看到。在这种情况下,javascript对象将检查DOM并窥视元素的某些属性(位置,宽度和高度等)。它不会直接修改DOM。

我正在尝试为此使用转发引用,但似乎无法理解将refs={...}放在何处

...我将其放入由React.forwardRef创建的对象中,还是从调用的前向引用对象中引用它?

enter image description here

这是我完整的AppContainer对象

import React from 'react'
import InfoBoxRings from './infobox_rings'
import styled from 'styled-components';

import AbcLogoInner from './abc_logo_inner'
import MarbleInEffect from './marble_in_effect'


const rings = [
  { key: 2,
    name: "AAAAAA",
    top_pos: 10,
    left_pos: 6,
    blurb: "Lorem ipsum dor ameet},
  { key: 3,
    name: "The abc Way",
     top_pos: 50,
    left_pos: 2,
    blurb: "Lorem ipsum dor ameet},

  },
  { key: 4,
    name: "A New Generation of Apps",
    top_pos: 2,
    left_pos: 0,
    blurb: "Lorem ipsum dor ameet},

  },
  { key: 5,
      top_pos: 90,
    left_pos: 2,
    blurb: "Lorem ipsum dor ameet},

  },
  { key: 6,
     top_pos: 60,
    left_pos: 6,
    blurb: "Lorem ipsum dor ameet},
    blurb: ""
  }




const StyledLogoContainer = styled.div`
  position: relative;
  height: 310px; 
  width: 336px;

  top: 8%;
  left: 5%;

  @media (max-width: 700px) {
    height: 155px; 
    width: 168px;
  }
`


class AppContainer extends React.Component {
  constructor(props) {
    super()
    this.abc_logo_inner_ref = React.createRef()
    this.marbles_container_ref = React.createRef();

    this.effect = new MarbleInEffect(
      this.abc_logo_inner_ref,
      this.marbles_container_ref
    )

    this.examineInRelation = this.examineInRelation.bind(this)
  }

  state = {
    ringsLoaded: true,
    focused_ring: 0
  }

  examineInRelation(_this_ring) {
    this.effect.examineInRelation(this, _this_ring)
  }

  componentDidMount() {
    const marbles_container = this.marbles_container_ref

    this.timeout = setTimeout(() => {
      console.log("checking the positionings of all the rings")

      rings.map((ele,i) => {
        var ele, i
        var _this_ring = marbles_container.current.getInfoBoxRef(i)
        this.examineInRelation(this, _this_ring)
      })
    }, 1000 + (Math.random()*1000))
  }

  componentWillUmount() {
    clearTimeout(this.timeout)
  }

  _focusOnRing =(newRing) => {
    this.setState({focused_ring: newRing})
  }

  render () {
    var {focused_ring, ringsLoaded} = this.state
    const MarblesContainer = ringsLoaded ?  React.forwardRef((props, ref) => {
      return (
        <InfoBoxRings
          ref={this.marbles_container_ref}
          effect={this.effect}
          rings={rings}
          focused_ring={focused_ring}
          focusOnRing={this._focusOnRing} />
        )
      }
    ) : ''

    const AbcLogoContainer = ringsLoaded ?  React.forwardRef((props, ref) => {
      return (
        <StyledLogoContainer>
          <AbcLogoInner {...props}
                           ref={this.abc_logo_inner_ref}
                           effect={this.effect}
                           focused_ring={focused_ring} />

        </StyledLogoContainer>

          )
      }
    ) : ''

    return (
      <div>
        <AbcLogoContainer />
        <MarblesContainer ref={this.marbles_container_ref}/>
      </div>
    )
  }
}

export default AppContainer

这是我总结的目标(有点雄心勃勃):

我想比较屏幕上的所有对象(1)徽标和包含1个或多个对象InfoBoxRings('marbles')的MarblesContainer。在初始化从rings变量初始化的数组时,我想在树下转发ref,以便可以从恰好位于{{1 }}(此处未显示)。

import MarbleInEffect from './marble_in_effect'对象被粗略地附加到构造函数中的AppContainer,可以看出。它所做的所有工作都会创建两个ref,并将它们附加到effect对象中,这是我要为效果设置动画的代码。 (不用担心,因为我将只声明性地不直接更改DOM。)

我的问题是我的裁判确实有effect个对象-我可以看到和检索---但是那些.current对象的行为不像DOM Elements,我似乎打电话给我,请不要紧急使用.current或其他HTML方法

当我在控制台中检查它们时,它们看起来像这样:

enter image description here

基本上,这些不是我想要的DOM元素。我哪里做错了?

更新2019-11-20:

.innerHTML

import React from 'react' import styled from 'styled-components'; import AbcLogoInner from './abc_logo_inner' import MarbleInEffect from './marble_in_effect' import InfoBox from "./info_box"; const rings = [ // omitted ... ] const StyledLogoContainer = styled.div` position: relative; height: 310px; width: 336px; top: 8%; left: 5%; @media (max-width: 700px) { height: 155px; width: 168px; } ` class AppContainer extends React.Component { constructor(props) { super() this.abc_logo_inner_ref = React.createRef() this.marbles_container_ref = React.createRef(); this.marbles_refs_array = [] rings.map((ele,i) => { this.marbles_refs_array[i] = React.createRef(); }) this.examineInRelation = this.examineInRelation.bind(this) } state = { ringsLoaded: true, focused_ring: 0 } examineInRelation(_this_ring) { this.effect.examineInRelation(this, _this_ring) } componentDidMount() { console.log("AppContainer componentDidMount.......") this.effect = new MarbleInEffect( this.abc_logo_inner_ref, this.marbles_container_ref ) if (this.abc_logo_inner_ref.current) { var logo_inner = this.abc_logo_inner_ref.current } } componentWillUmount() { clearTimeout(this.timeout) } _focusOnRing =(newRing) => { this.setState({focused_ring: newRing}) } render () { var {focused_ring, ringsLoaded} = this.state const effect = this.effect return ( <div> <StyledLogoContainer> <AbcLogoInner {...this.props} ref={this.abc_logo_inner_ref} effect={this.effect} focused_ring={focused_ring} /> </StyledLogoContainer> {ringsLoaded ? <div> {rings.map((ele, i) => <InfoBox infoboxRef={this.marbles_refs_array[i]} effect={effect} key={ele.key} id={ele.key} name={ele.name} top_pos={ele.top_pos} left_pos={ele.left_pos} blurb={ele.blurb} focusOnRing={this._focusOnRing} rings_visible={true} blurb_visible={(focused_ring === ele.key)} rings_spinning={(focused_ring === ele.key)} />) } </div> : ''} </div> ) } } export default AppContainer

info_box.js

当从AppContainer传递到InfoBox时,我得到的所有infoboxRef均为空

0 个答案:

没有答案