Как прокрутить элемент в соответствии с идентификатором с помощью ScrollView?

#reactjs #react-native #react-native-android #scrollview #react-native-ios

#reactjs #react-native #react-native-android #scrollview #react-native-ios

Вопрос:

Я хочу прокрутить до вершины со ссылкой на идентификатор изначально для данного списка элементов, поэтому я пишу следующий код —

     import React, {useState, useEffect, useRef} from 'react';
import {
  SafeAreaView,
  ScrollView,
  TouchableOpacity,
  ActivityIndicator,
} from 'react-native';
import axios from 'axios';
import NotExpandedVaccineComponent from '../../../../components/Home/NotExpandedVaccineComponent';
import ExpandedVaccineComponent from '../../../../components/Home/ExpandedVaccineComponent';
import {ROOT} from '../../../../services/ApiUrl';
export default function VaccinationListScreen(props) {
  const {navigation} = props;
  const [data, setData] = useState([]);
  const [changedstatus, setChangedStatus] = useState(null);
  const [loading, setisLoading] = useState(true);
  const scrollRef = useRef(null);
  let id = props.route.params.id;
  let interbalIdArr;
  const childdob = props.route.params?.childdob;
  const selectedid = props.route.params?.selectedid;

  const [expand, setExpand] = useState({});
  let vaccinenameselected = props.route.params?.vaccineitem;
  console.log('vaccine selected', vaccinenameselected);
  const changevaccinestatus = (value) => {
    setChangedStatus(value);
  };
  const handleClickOnYourElem = (y) =>
    scrollRef.current.ScrollTo({y, animated: true});
  const getData = () => {
    let url = `${ROOT}/children/${id}/vaccinations`;

    axios
      .get(url)
      .then(function (res) {
        console.log(res);
        setData(res.data.content);
        setisLoading(false);
        const items = res.data.content;
        items.map((a) => {
          const arr = a.vaccine_list.map((a) => a.vaccineInternalId);
          console.log('arr', arr);
          if (arr.includes(selectedid)) {
            console.log('jj', a.id);
            setExpand({[a.id]: true});
          }
        });
      })
      .catch(function (err) {
        console.log(err);
      });
  };

  useEffect(() => {
    getData();
    selectedid amp;amp; handleClickOnYourElem(selectedid);
  }, [changedstatus, loading]);

  function handleOnPress(id, item) {
    setExpand((prev) => {
      let toggleId = true;

      if (prev[id]) {
        toggleId = {[id]: false};
      } else {
        toggleId = {[id]: true};
      }

      return {...toggleId};
    });
  }
  if (data == '' || loading == true) {
    return (
      <ActivityIndicator
        color="#FF1493"
        size="large"
        style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}
      />
    );
  } else {
    return (
      <SafeAreaView>
        <ScrollView horizontal pagingEnabled ref={scrollRef}>
          {data != '' amp;amp;
            data !== undefined amp;amp;
            data !== null amp;amp;
            data.map((item) => {
              const selected = item.vaccine_list
                .map((a) => a.vaccineInternalId)
                .includes(selectedid);
              return (
                <TouchableOpacity
                  key={item.id}
                  style={{
                    paddingLeft: 10,
                    paddingRight: 10,
                  }}
                  onPress={() => handleOnPress(item.id, item)}>
                  {expand[item.id] ? (
                    <ExpandedVaccineComponent
                      item={item}
                      id={id}
                      navigation={navigation}
                      changevaccinestatus={changevaccinestatus}
                      childdob={childdob}
                    />
                  ) : (
                    <NotExpandedVaccineComponent item={item} />
                  )}
                </TouchableOpacity>
              );
            })}
        </ScrollView>
      </SafeAreaView>
    );
  }
}
 

Но когда я выполняю то же самое, я получаю, что null не является объектом (вычисление ‘scrollRef.current.scrollTo’).

Почему это так? Не мог бы кто-нибудь указать, где я ошибся? Застрял с давних пор, пожалуйста, помогите мне. Любые выводы были бы замечательными, спасибо.

Ответ №1:

кажется , ты забываешь current .

Вам нужно использовать его следующим образом:

 ...
const scrollRef = useRef();

const handleClickOnYourElem = y =>scrollRef.current.ScrollTo({y,animated: true});
  
return (
  <ScrollView ref={scrollRef} >
...
 

И это не связано с вашим Q, а вместо

           {data != '' amp;amp;
            data !== undefined amp;amp;
            data !== null amp;amp;
            data.map((item) => {
 

Вы можете просто использовать: data?.map((item=> ...

И не нужно создавать дополнительный массив для проверки выбранного:

Вы можете заменить это:

               const selected = item.vaccine_list
                .map((a) => a.vaccineInternalId)
                .includes(selectedid);
 

с помощью:

   const selected = (item.vaccine_list.find(({vaccineInternalId})=>vaccineInternalId===selectedid))?.vaccineInternalId
 

Комментарии:

1. Я получаю null не является объектом (вычисление ‘scrollRef.current. scrollTo’)

2. попробуйте const scrollRef = useRef(); и посмотрите, что произойдет

3. все та же ошибка

4. удалите <SafeArea…> и проверьте

Ответ №2:

На основе отредактированного сообщения это должно быть изменено:

   useEffect(() => {
    getData();
    selectedid amp;amp; handleClickOnYourElem(selectedid);
  }, [changedstatus, loading, selectedid]); // need "selectedid" as dependency
 

// Ниже приведено старое содержимое, игнорировать

Попробуйте эти

 const vaccineRef = useRef(null);

ref={vaccineRef}

React.useLayoutEffect(() => {
  vaccineRef.current.scrollTo(selectedid);
}, [selectedid]);
 

Комментарии:

1. вы хотите, чтобы я добавил useLayoutEffect внутри useEffect?

2. Нет, я предлагал заменить несколько строк и добавить дополнительную useLayoutEffect . Извините за неясный ответ. Обновлено и надеюсь, что это поможет.

3. где я должен использовать эффект useLayoutEffect? Нужно ли мне это?

4. Он выдает scrollViewRef.current.scrollTo не является функцией, почему это так?