Как остановить постоянное повторное отображение массива

#javascript #reactjs #typescript #react-native

Вопрос:

У меня есть массив изображений, в котором я обновляю каждое значение, когда нажимаю кнопку в react и выбираю изображение. Однако массив постоянно обновляется, когда я этого хочу, только когда выбираю изображение. Вот мой код:

    function OnboardingUploadPhotos() {
  const [modalVisible, setModalVisible] = useState(false);
  const [permissionStatus, setPermissionStatus] = useState('');
  const [files, setFiles] = useState<string[]>([]);
  const [fileArray, setFileArray] = useState<string[]>(['', '', '', '', '', '', '']);

  const setPermissions = useCallback(val => {
    setPermissionStatus(val);
  }, [setPermissionStatus]);

  const setIsModalVisible = useCallback(val => {
    setModalVisible(val);
  }, [setModalVisible]);

  async function fetchAssets() {
    const recentCameraRoll = await MediaLibrary.getAssetsAsync({first: 11});
    setFiles(recentCameraRoll.assets.slice(1).map(file => file.uri));
  }

  function replaceFileState(file: string, index: number) {
    let f = [...fileArray];
    f[index] = file;
    setFileArray(f);
  }

  useEffect(() => {
    fetchAssets();
  }, [fetchAssets]);

  return (
      <View>
        {permissionStatus ?
            <Modal style={styles.bottomModalView} isVisible={modalVisible} backdropOpacity={0}
                   onBackdropPress={() => setModalVisible(false)}>
              <View style={styles.modal}>
                <TouchableOpacity>
                  <Text style={{
                    borderBottomWidth: 1,
                    borderBottomColor: '#FFF',
                    color: '#FFF',
                    textDecorationLine: 'underline',
                    alignSelf: 'flex-end',
                    justifyContent: 'center',
                    paddingTop: 40
                  }}>All photos</Text>
                </TouchableOpacity>
                <ScrollView horizontal={true} scrollEnabled={true}
                            contentContainerStyle={{justifyContent: 'center', alignItems: 'center'}}>
                  {files.map((file, index) => {
                    return (
                        <TouchableWithoutFeedback key={index} onPress={() => replaceFileState(file, index)}>
                          <Image
                              key={file}
                              style={{width: 100, height: 100, marginLeft: 10, marginRight: 10, borderRadius: 4}}
                              source={{uri: file}}
                          />
                        </TouchableWithoutFeedback>
                    );
                  })}
                </ScrollView>
                <Text style={{fontSize: 22, color: '#FFF', marginLeft: 20, marginBottom: 20}}>Your photos</Text>
              </View>
            </Modal> :
            null
        }
        <Text>Upload your photos</Text>
        <View style={{flexDirection: "row", flexWrap: "wrap", justifyContent: 'space-evenly'}}>
          {fileArray.slice(0,6).map((image, index) => {
            console.log(fileArray)
            return (
                image != '' ?
                    <Image
                        key={image}
                        style={{width: 100, height: 100, borderRadius: 100}}
                        source={{uri: image}}
                    /> :
                    <OnboardingPhoto key={index} setStatus={setPermissions} setModal={setIsModalVisible}/>
            )
          })}
        </View>
      </View>
  );
}
 

Это модальный режим, в котором все пользователи получают последние изображения, и по щелчку каждого изображения он заменяет пустое изображение-заполнитель изображением пользователей на экране. Однако он постоянно повторяется. Я скажу, чтобы вы положили его в useEffect , но я не знаю, где! Любая помощь была бы отличной, спасибо!

Ответ №1:

Я думаю, вам нужно определить key свойство TouchableWithoutFeedback компонента.

Смотрите рекомендации здесь: https://reactjs.org/docs/lists-and-keys.html

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

1. Будет ли это то же самое для осязаемой емкости, поскольку она расширяет возможности осязаемой без обратной связи?

2. Кроме того, это работает и останавливает повторную передачу фотографий, но у меня есть console.log(файловый массив), который все еще повторяется каждый раз?

3. Вот как работает реакция. Где ваша консоль? выписка из журнала размещена? React вызовет ваш компонент много раз, но это не обязательно приведет к новому рендерингу. «Ключ» позволяет реагировать, чтобы увидеть, изменилось ли что-то.

4. Ах, да, это как раз за пределами моей функции возврата jsx. Я никогда не знал, что на самом деле делал Ки! Спасибо Тебе!

5. Вы устанавливаете ключевое свойство элемента изображения для самого изображения. Это не сработает. Вместо этого используйте индекс. На самом деле, не делайте этого тоже — используйте что-то вроде image-${index} этого, чтобы ваши ключи не сталкивались с клавишами без обратной связи. Все ключи должны быть уникальными.

Ответ №2:

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

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

1. Я решил свою первоначальную проблему, но вместо этого моя работа теперь постоянно обновляется! Есть какие-нибудь идеи?