Смущает насчет переадресованных ссылок React

Я пытаюсь сделать что-то немного сложное с переадресованными ссылками React, и кое-что я не совсем понимаю.

Я пытаюсь использовать перенаправленные ссылки в React для создания набора дочерних узлов, все из которых можно увидеть с помощью перенаправленных ссылок на один объект javascript. В этом случае объект javascript исследует DOM и взглянет на некоторые атрибуты элемента (положение, ширину и высоту и т. Д.). он не будет напрямую изменять DOM.

Я пытаюсь использовать для этого перенаправленные ссылки, но я не понимаю, где разместить refs={...}

... поместить его в объект, созданный React.forwardRef, или я могу ссылаться на него из вызываемого объекта forward ref?

Вот мой полный объект 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), логотип и MarblesContainer, который содержит 1 или несколько объектов InfoBoxRings ("шарики"). При инициализации этого массива, который инициализируется изrings переменной, я хочу перенаправить ссылку вниз по дереву, чтобы я мог ссылаться на узел React из логики более высокого порядка, которая просто случайно находится в import MarbleInEffect from './marble_in_effect' (здесь не показано).

в effectКак видно, объект грубо прикреплен к AppContainer в конструкторе. Все, что он делает, создает две ссылки и присоединяет их к объекту эффекта, в котором находится код, который я хочу анимировать. (Не волнуйтесь, поскольку я буду изменять DOM только декларативно, а не напрямую.)

Моя проблема в том, что у моих рефов есть .current объекты, которые я могу видеть и извлекать, но эти .current объекты не ведут себя как элементы DOM, я не могу позвонить мне, пожалуйста, не срочно .innerHTML на них или другой метод HTML

когда я рассматриваю их в консоли, они выглядят так:

по сути, это не те элементы DOM, которые я искал. Где я неправ?

ОБНОВЛЕНИЕ 2019-11-20:

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 является

import React from 'react'
import styled from 'styled-components'
import Rings from './rings'

import BlurbBox from './blurb_box'

const StyledH1 = styled.h1`
  font-size: 1.2em;
  width: 100%;
`

const StyledInfoBox = styled.div`
  border: solid 1px red;
  text-align: center;
  position: absolute;
  width: 100px;
  height: 100px;
  cursor: pointer;
`

class InfoBox extends React.Component {
  constructor(props) {
    super(props)

    // choose one of 8 carrdinal directions
       this.state = {
      name: (props.name ?  props.name : "")
    }
  }


  componentDidMount() {
    let marble = this.props.infoboxRef
    console.log("•••••• marble inner html", marble.innerHTML) // does not work
  }
  render() {
    const top_pos = this.props.top_pos || 100
    const left_pos = this.props.left_pos || 400
    const {name, id, rings_visible, blurb, rings_spinning} = this.props
    const {top_offset, left_offset} = this.state

    // TODO: rename rings_visible to disclosed

    var calculated_top = (rings_visible ? top_offset : 0)
    var calculated_left =  (rings_visible ? left_offset : 0)

    if (rings_visible) {
      // console.log("calculated_top", calculated_top)
      // console.log("calculated_left", calculated_left)
    }

    return (
      <div ref={this.props.infoboxRef}>
        <StyledInfoBox  onClick={() => { this.buttonRef.current.blur(); this.props.focusOnRing(this.props.id) }}
         style={{top: top_pos + "%",
                left: left_pos + "%"}}>

          <Rings visible={rings_visible}
                 animation_sequence={rings_spinning ? ['spinning', ''] : [] }/>

          <div className="vertical-center-container">
            <StyledH1>
              <button ref={this.buttonRef} href="#" value={name}>{name}</button>
            </StyledH1>
          </div>

          <BlurbBox blurb={blurb} rings_visible={rings_visible}>

          </BlurbBox>
        </StyledInfoBox>
      </div>
    )
  }
}

export default React.forwardRef((props, ref) => <InfoBox {...props} infoboxRef={ref} />)

что я получаю, что все infoboxRef равны нулю при передаче из AppContainer в InfoBox

0 ответов

Другие вопросы по тегам