useEffect не работает при изменении состояния - PullRequest
0 голосов
/ 05 октября 2019

У меня есть экран (MyPics.js), который показывает коллекцию изображений, которые пользователь выбирает на другом экране. Я получаю выбранные изображения из asyncstorage.

Все работает нормально, если я выбираю изображения и затем перезагружаю симулятор. Когда я перехожу на экран MyPics.js, я вижу все изображения, сохраненные в AsyncStorage из предыдущих выборов изображений.

  const MyPicsScreen = props => {
    const [picList, setpicList] = useState([]);

    useEffect(() => {
      console.log("I'm in!! picList data is: " +  picList);
      AsyncStorage.getItem("mypics").then((response) => {
      const currentData = JSON.parse(response);
      setpicList(currentData);
      console.log("Current picList data will be: " + currentData);
    });
   }, []);


  return (
<View style={styles.wrapper}>
  <ScrollView>
    <View style={{flexDirection: "column", justifyContent: "center", alignItems: "center"}}>

      {picList ? picList.map((item, index) => {
        return (
            <View key={index} style={styles.viewItem}>
              <Image style={{width: 200, height: 131}} source={Images[PicList[item][3]]} />
            </View>
          );
        }
      ) : <View><Text>You haven't selected any pics yet</Text></View>}

    </View>
  </ScrollView>
</View>
   );
 };

В терминале отображается:

  I'm in!! picList data is:  //No data, as expected. Nothing is retrieved yet, then...
  Current picList data: pic001,pic007,pic099 // That shows, correctly, what's stored and screen shows those images 

Но если я добавлю изображенияновые изображения не отображаются, пока я не перезагружу симулятор. Кроме того, в консоли не читается информация, поэтому не используется useEffect для получения данных и сброса состояния.

Я предполагаю, что возврат к экрану MyPics вызывает повторную визуализацию, но я могунеправильно.

Я сделал 3 кнопки на экране MyPics.js, который вручную запускает либо removeItem, либо setItem, либо getItem в asyncstorage, который затем удаляет или устанавливает или получает изображения, а затем обновляет состояние picList.

Тоработает.

Когда я использую кнопки, он получает или удаляет ранее установленные изображения или устанавливает новое изображение, и экран повторно отображает, чтобы показать изменение состояния.

Таким образом, useEffect не работает, когдаЯ перехожу на экран MyPics.js. Он запускается только при первом рендеринге.

Когда я добавляю состояние picList как зависимость,

  }, [picList]);

работает, но консоль работает в бесконечном цикле.

Это нормально? Должен ли я просто игнорировать бесконечно прокручиваемую консоль или я пропускаю шаг? Должен ли я использовать слушатель фокуса для повторного рендеринга страницы при повторном посещении, поскольку мне нужны только новые данные, когда я возвращаюсь на экран MyPics.

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

После большой боли и потерянного времени это работает:

 useEffect(() => {
  AsyncStorage.getItem("mypics").then((response) => {
  setpicList(JSON.parse(response);
});
}, []);

const getList = useCallback(() => {
  AsyncStorage.getItem("mypics").then((value) =>{
  setpicList(JSON.parse(value));
});
}, [picList]);

Некоторые очень практичные примеры для функциональных компонентов можно найти в этой теме:

Реагировать на навигацию didfocusпрослушиватель событий работает по-разному между компонентом класса и функциональным компонентом

При возвращении к экрану необходимо обнаружение фокуса, чтобы снова использовать функцию useEffect.

0 голосов
/ 05 октября 2019

Из документов

Если вы хотите запустить эффект и очистить его только один раз (при монтировании и размонтировании), вы можете передать пустой массив ([]) в качестве второго аргумента. Это говорит React, что ваш эффект не зависит от каких-либо значений из реквизита или состояния, поэтому его не нужно повторно запускать. Это не обрабатывается как особый случай - это следует непосредственно из того, как всегда работает массив зависимостей.

Таким образом, передача пустого массива в useEffect примерно эквивалентна (за исключением useEffect пожаров) после начальная краска) функции componentDidMount и componentWillUnmount компонентов класса.

...