question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Getting Invalid warnings when creating own ref

See original GitHub issue

What I Expect When I am mid scroll, and the user changes the input, the scroll index should jump back to the top of the list once the new data loads.

What is happening I was able to reset the scroll back to the top, but now I am getting warnings that the list ref and the onItemsRendered is invalid. Even though they are warnings they are hindering the list from populating. I have tested this by taking out the scrollToTop logic and replacing the List ref with the ref provided by InfiniteLoader.

Am I implementing the new ref incorrectly?

image image

The Code

import React from 'react';
import PropTypes from 'prop-types';
import Downshift from 'downshift';
import styled from 'styled-components';
import { FixedSizeList as List } from 'react-window';
import InfiniteLoader from 'react-window-infinite-loader';
import MenuItem from '@material-ui/core/MenuItem';
import { withStyles } from '@material-ui/core/styles';

import BaseComponent from '../BaseComponent';

export class SearchFieldInfiniteScrollComponent extends BaseComponent {
  listRef = React.createRef();
  scrollToTop() { 
    this.listRef.current.scrollToItem({ align: 'start' });
  } 

  render() {
    const {
      dataArray,
      dropdownWidth,
      handleInput,
      handleSelection,
      isFirstListRender,
      isRowLoaded,
      itemContent,
      listHeight,
      loadedRowCount,
      loadingIndicator,
      loadMoreRows,
      placeholder,
      rowHeight,
      totalCount,
      threshold,
    } = this.props;

    return (
      <SearchContainer>
        <Downshift
          onChange={handleSelection}
          stateReducer={stateReducer}
          itemToString={item => (item ? item.value : '')}
        >
          {({ getInputProps, getMenuProps, isOpen, highlightedIndex, getItemProps }) => {
            return (
              <div>
                <Input
                  {...getInputProps({
                    onChange: e => {
                      if (!e.target.value.length) {
                        this.scrollToTop();
                      }

                      return handleInput(e);
                    },
                  })}
                  placeholder={placeholder}
                />
                <UnorderedList {...getMenuProps()}>
                  {isOpen && dataArray && (
                    <InfiniteLoader
                      isItemLoaded={isRowLoaded}
                      loadMoreItems={loadMoreRows}
                      itemCount={loadedRowCount}
                      threshold={threshold}
                    >
                      {({ onItemsRendered }) => (
                        <List
                          ref={this.listRef}
                          height={listHeight}
                          onItemsRendered={onItemsRendered}
                          itemCount={loadedRowCount}
                          itemSize={rowHeight}
                          width={dropdownWidth}
                        >
                          {({ index, style }) => {
                            let content = (
                              <Loading>
                                {(isFirstListRender || index < totalCount) && loadingIndicator}
                              </Loading>
                            );

                            if (dataArray[index]) {
                              content = (
                                <StyledMenuItem
                                  selected={highlightedIndex === index}
                                  component='div'
                                  {...getItemProps({
                                    key: itemContent,
                                    index,
                                    item: dataArray[index],
                                  })}
                                >
                                  {itemContent(index)}
                                </StyledMenuItem>
                              );
                            }

                            return (
                              <RowContainer key={`${index}-${Math.random()}`} style={style}>
                                {content}
                              </RowContainer>
                            );
                          }}
                        </List>
                      )}
                    </InfiniteLoader>
                  )}
                </UnorderedList>
              </div>
            );
          }}
        </Downshift>
      </SearchContainer>
    );
  }
}

export default withStyles(styles, { withTheme: true })(SearchFieldInfiniteScrollComponent);

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
bvaughncommented, Sep 6, 2019

ref is not what you think it is, as @nihgwu mentioned and as the docs I linked to above indicate 😃 It’s a ref (function) you’re meant to pass on and attach to the inner list so that infinite loader gets a ref to that list.

{({ onItemsRendered, ref }) => (
  <List
    ref={list => {
      ref(list); // Give InfiniteLoader a reference to the list
      this.listRef.current = ref; // Set your own ref to it as well.
    }}
  />
)}

I’m going to close this issue, since I’m pretty sure it’s been been answered now. If you are still running into any additional problems, it would probably be best provide a complete runnable repro in Code Sandbox. 😃

1reaction
sgupcommented, Dec 15, 2021

Was also stuck on this, got auto-scroll to bottom like this:


const [listRef, setListRef] = useState(null)

// Scroll To Bottom
useEffect(() => {
  listRef?.scrollToItem?.(data.length - 1)
}, [listRef, data.length])

// ...

<>
  // ...
  {({ onItemsRendered, ref: setRef }) => {
    return (
      <FixedSizeList
        itemCount={data?.length}
        onItemsRendered={onItemsRendered}
        ref={(list) => {
          // @ts-ignore next-line
          setRef?.(list); // Gives the list ref to the parent InfiniteLoader
          setListRef(list);
        }}
        height={height}
        width={width}
        itemSize={50}
      >
        {RenderRow}
      </FixedSizeList>
    );
  }}
  // ...
</>
Read more comments on GitHub >

github_iconTop Results From Across the Web

Why do I get a warning icon when I add a reference to an MEF ...
When I create a test Console App project and add a project reference to the plugin project, I get a warning icon (yellow...
Read more >
Invalid Hook Call Warning - React
There are three common reasons you might be seeing it: You might have mismatching versions of React and React DOM. You might be...
Read more >
Invalid Missing NuGet Package Reference Warnings
To get past the reference error and warning icons, all I need to do is highlight the package in question, and expand the...
Read more >
NuGet Errors and Warnings Reference - Microsoft Learn
Complete reference for warnings and errors issued from NuGet during various NuGet operations.
Read more >
Invalid Reference Error - OutSystems 10 Documentation
You have a Reference to an Action that has a Parameter in which the definition includes a Multi-tenant entity and the Show Tenant...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found