0

I have a list of items that are conditionally rendered onto my page- I'd like each of them to have a unique ref based on their ID.

I tried creating a ref for each item within the constructor, but it seems either because the refs are created before the render, or because of my own error- each ref is set to null.


class EmailList extends Component {
  constructor(props) {
    super(props)

    this.state={
      emailreports: []
    }
    props.emailreports.forEach(thing => {
      this[`${thing.id}_ref`] = React.createRef()
     });
    }

  componentDidMount(){
    this.setState({
      emailreports: this.props.emailreports
    })
  }

  render() {
  const { emailreports } = this.state;
  return (
    <div>
      
      <section>
        <h5>Email Reports</h5>
        <ul>

          {
            emailreports.length > 0
            ?
            <>
            {
              emailreports.map((report, i) => {
                return <EmailReportItem ref={this[`${report.id}_ref`]}  />
              })
            }
            </>
            :
            <section >
              <div className="text-center">You do not currently have access to email report data.</div>
            </section>
          }
        </ul>
      </section>
  </div>
    )
  }
}

export default connect(mapStateToProps)(EmailList);

The following image is the result of the above load:

Refs

mg2019
  • 191
  • 17
  • It seems the refs are created. Where are you console logging this? – Drew Reese Feb 19 '21 at 22:19
  • I put in a temporary button that logs `this` just to see if the refs are created. Indeed they are created- however it doesn't seem they are assigned to anything. Is this true? – mg2019 Feb 19 '21 at 22:21
  • How does the `EmailReportItem` component handle received refs? Have you also instead tried creating a single ref to hold an array to generated refs for each email report? – Drew Reese Feb 19 '21 at 22:25
  • 1
    I bet if you replace `EmailReportItem` with say `input` it will work. But what are you trying to achieve? There should be a better way. – Nadia Chibrikova Feb 19 '21 at 22:31
  • @DrewReese I'm not sure how I would do that- doesn't the forEach loop accomplish the same thing? How can that be done? – mg2019 Feb 19 '21 at 22:32
  • @NadiaChibrikova That's definitely a possibility... I'm trying to perform a `.scrollIntoView()` on load based on the match parameters. Is there an easier way to select an element for `.scrollIntoView()`? – mg2019 Feb 19 '21 at 22:34
  • 1
    That's funny that you are trying to scroll elements into view, the example I was going to try and share is essentially exactly this. https://stackoverflow.com/a/64981228/8690857 It uses functional components to the main ref used to store the array of refs is created from the `useRef` hook, but conceptually it is the same. – Drew Reese Feb 19 '21 at 22:38
  • 1
    As an option you can pass a flag into the component you want to scroll into view, at least each child component will keep its own single ref and you won't need to struggle with forwarding refs – Nadia Chibrikova Feb 19 '21 at 22:38
  • 1
    What Nadia says, or you can wrap each mapped `EmailReportItem` in a div parent that consumes the ref. – Drew Reese Feb 19 '21 at 22:39
  • Thank you both! I will give this a shot- though not entirely sure I understand. @DrewReese regarding the example provided- is it possible to use `useRef([])` in a Class based component? – mg2019 Feb 19 '21 at 22:42
  • 1
    No, you'd use `createRef` still to create the single main ref. Functional components need to generate it a bit differently because if they used `createRef` it would be recreated each render cycle and all the refs would be lost/reset. – Drew Reese Feb 19 '21 at 22:44
  • 1
    Just passing a property like `` and inside `EmailReportItem` you check the flag and scroll to an element (with a ref again, but that'll be the only ref there) – Nadia Chibrikova Feb 19 '21 at 22:54
  • @DrewReese & Nadia you both solved it! I ended up wrapping in a div and the refs have now assigned! Thanks so much again!!!!! – mg2019 Feb 19 '21 at 22:54
  • 1
    Lovely, glad you solved your problem! – Nadia Chibrikova Feb 19 '21 at 22:55
  • 1
    Welcome, glad it all works for you now. – Drew Reese Feb 19 '21 at 23:15

0 Answers0