Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

renderOnScroll causing bug #77

Closed
Jaaneek opened this issue Dec 18, 2020 · 5 comments
Closed

renderOnScroll causing bug #77

Jaaneek opened this issue Dec 18, 2020 · 5 comments
Assignees
Labels
bug Something isn't working Fixed on Next Release
Milestone

Comments

@Jaaneek
Copy link

Jaaneek commented Dec 18, 2020

FlatList Version
:1.4.3

Describe the bug
: Enabling renderOnScroll throws error when searchTerm doesnt match any elements
Steps to reproduce the behavior
:
Set renderOnScroll to true
search props:

search={{
            by: ["title", "message"],
            term: searchTerm,
            caseInsensitive: true,
          }}

Render around 400 elements.
set searchTerm to something like "8218132873873nrui3" so that it wont match anything.
set searchTerm to something that will match a few elements.

Expected behavior
:after a short moment error will appear: TypeError: Cannot set property 'scrollTop' of null

Desktop (please complete the following information):

  • OS: Windows
  • Browser: Chrome
  • Version:87.0.4280

Smartphone (please complete the following information):

  • Device:
  • OS:
  • Browser:
  • Version:

Screenshots
image
image
image

@ECorreia45 ECorreia45 self-assigned this Dec 25, 2020
@ECorreia45 ECorreia45 added this to the Release 1.5.0 milestone Dec 25, 2020
@ECorreia45
Copy link
Collaborator

ECorreia45 commented Dec 25, 2020

Sorry for delay in noticing this. Working on a fix right away.

@ECorreia45
Copy link
Collaborator

@Jaaneek I was not able to reproduce this, can you provide me with more details, please?

  • get me the full code of Flatlist component with all the props you are setting (even the full code of the file where you are using it if posible)
  • give me all the errors you are seeing(you gave me error 1 of 2).
  • step by step of what you did. I dont believe this has to do with the search because one of the requirements of renderOnScroll is that there must be a non-empty list and you must not be using the pagination props. Please note the step by step.
  • does the error appear right after you stop typing or some moments after?

@Jaaneek
Copy link
Author

Jaaneek commented Jan 1, 2021

import React, { useEffect, useState } from "react";
import {
  Button,
  DialogActions,
  DialogTitle,
  TextField,
  useMediaQuery,
} from "@material-ui/core";
import { Dialog, DialogContent } from "@material-ui/core";
import styles from "../SettingsPage.module.scss";
import SingleEventContainer from "../../../EventComponents/SingleEventContainer/SingleEventContainer";
import UseIcsImport from "./UseIcsImport";
import { useMutation } from "react-apollo";
import ALL_EVENTS from "../../../ApolloQueries/ALL_EVENTS";
import ADD_EVENTS from "../../../ApolloQueries/ADD_EVENTS";
import FlatList from "flatlist-react";
import Checkbox from "@material-ui/core/Checkbox";
import { FormControlLabel } from "@material-ui/core";
const IcsImportButton = () => {
  const [isOpen, setIsOpen] = useState(false);
  const isMobile = useMediaQuery("(max-width: 767px)");
  return (
    <div className={styles.buttonLeftContainer}>
      <Button
        onClick={() => setIsOpen(true)}
        variant="contained"
        color="primary"
        className={styles.buttonLeft}
      >
        Import ICS file
      </Button>
      {isOpen && (
        <IcsImportDialog
          title="Import events"
          show={isOpen}
          handleClose={() => setIsOpen(false)}
          isMobile={isMobile}
        ></IcsImportDialog>
      )}
    </div>
  );
};

const IcsImportDialog = ({ show, handleClose, isMobile, title }) => {
  const [events] = UseIcsImport();
  const [addEvents] = useMutation(ADD_EVENTS);
  const [searchTerm, setSearchTerm] = useState("");
  const [selectedEvents, setSelectedEvents] = useState([]);
  const saveEvents = () => {
    if (!selectedEvents.some((x) => x)) {
      handleClose();
      return;
    }
    const mappedEvents = events
      .map(({ type, title, message, date, invokeDates }) => {
        return {
          title,
          message,
          invokeDates,
          date,
          eventTypeName: type,
        };
      })
      .filter((_, ind) => selectedEvents[ind]);
    addEvents({
      variables: { events: mappedEvents },
      refetchQueries: [{ query: ALL_EVENTS }],
    });
    handleClose();
  };
  useEffect(() => {
    const transformedEvents = events.map(() => false);
    setSelectedEvents(transformedEvents);
  }, [events]);

  const renderEvent = (event, index) => {
    return (
      <SingleEventContainer
        key={String(event.date) + String(event.title)}
        checked={!!selectedEvents[index]}
        onCheckboxChange={(checkValue) => {
          const newselectedEvents = selectedEvents.map((val, valIndex) => {
            if (valIndex === index) {
              return checkValue;
            }
            return val;
          });
          setSelectedEvents(newselectedEvents);
        }}
        {...event}
      ></SingleEventContainer>
    );
  };

  return (
    <Dialog
      scroll="paper"
      open={show}
      onClose={handleClose}
      fullScreen={isMobile}
      fullWidth
    >
      <DialogTitle className={styles.icsModalTitle}>
        <TextField
          fullWidth
          value={searchTerm}
          onChange={(e) => setSearchTerm(e.target.value)}
          placeholder="Seach events by title or message"
        ></TextField>
        <FormControlLabel
          className={styles.allEventsCheckbox}
          control={
            <Checkbox
              onChange={({ target: { checked: checkValue } }) => {
                setSelectedEvents(selectedEvents.map(() => checkValue));
              }}
              color="primary"
              name="Select all events checkbox"
            ></Checkbox>
          }
          labelPlacement="start"
          label="Select All"
        ></FormControlLabel>
      </DialogTitle>
      <DialogContent dividers className={styles.contentContainer}>
        <FlatList
          search={{
            by: ["title", "message"],
            term: searchTerm,
            caseInsensitive: true,
          }}
          list={events}
          renderItem={renderEvent}
          renderWhenEmpty={() => <div>List is empty!</div>}
          sortBy={["date"]}
          renderOnScroll
          srollToTop={false}
        />
      </DialogContent>
      <DialogActions>
        <Button variant="text" color="default" onClick={handleClose}>
          Close
        </Button>
        <Button variant="contained" color="primary" onClick={saveEvents}>
          Save Changes
        </Button>
      </DialogActions>
    </Dialog>
  );
};

export default IcsImportButton;

Error appears after some moment, the list is not empty but after providing searchTerm that doesnt match any of the elements it doesnt show anything just as supposed. It shouldnt show error because of that right?

@ECorreia45
Copy link
Collaborator

No you are correct. Ill retests using the cocktail of options as you have them and get back to you.

@ECorreia45
Copy link
Collaborator

ECorreia45 commented Jan 2, 2021

Seems like this issue was fixed in this commit:

0acaa81

in release 1.5.0

I will keep this issue opened until the next release and let you know about it.

Thank you

[details of the bug]
This is happening because in between the next browser paint and the list update(on search) the list is no longer rendered (due to no match) then when the code executes on the paint after there is no element to assign the scrollTop to (as the error says)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Fixed on Next Release
Projects
None yet
Development

No branches or pull requests

2 participants