Перерисовка компонентов приводит к сбою приложения - Expo

Я изучаю реакцию-native/expo.

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

Код JS Fiddle

Я загрузил сюда весь код, потому что он слишком длинный.

Порядок действий: заполните форму, при необходимости загрузите изображение и нажмите кнопку подтверждения.

Я пробовал использовать useCallback, но безуспешно.

МРЭ по запросу:

import React, { useState, useCallback } from 'react';
import { View, TextInput, Text, StyleSheet, TouchableOpacity, Image  } from 'react-native';
import KeyboardWrapper from '../KeyboardWrapper';
import * as ImagePicker from 'expo-image-picker';

const FormComponent = ({ onSave }) => {
  const [formData, setFormData] = useState({
    driverName1: '',
      });
const [images, setImages] = useState([]); // State to store captured images

// Function to handle image capture
  const handleCaptureImage = useCallback(async () => {
    const { status } = await ImagePicker.requestCameraPermissionsAsync();
    if (status !== 'granted') {
      alert('Camera permission is required to take pictures.');
      return;
    }
  
    try {
      const result = await ImagePicker.launchCameraAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        allowsEditing: false,
        aspect: [16, 9],
        quality: 1,
      });

      if (!result.cancelled && result.assets.length > 0) {
        // Add the new image URI to the images state
        setImages(prevImages => [...prevImages, result.assets[0].uri]);
      }
    } catch (error) {
      console.error('Error capturing image:', error);
    }
  }, []);

  const handleChangeEvent = useCallback((name, value) => {
    setFormData({ ...formData, [name]: value });
  }, [formData]);
 return (
    <KeyboardWrapper>
    <View style = {styles.container}>
      <View style = {styles.form}>
      <TextInput
        placeholder = "Sofer 1"
        value = {formData.driverName1}
        onChangeText = {(text) => handleChangeEvent('driverName1', text)}
        style = {styles.textInput}
      />
     {/* Display captured images */}
      <View style = {styles.formImgs}>
        {images.map((imageUri, index) => (
          <View key = {index} style = {styles.img}>
              {console.info('Image URI:', imageUri)}
            <Image
              source = {{ uri: imageUri }}
              style = {{ width: 100, height: 100 }}
            />
          </View>
        ))}
      </View>
      <View style = {styles.formAction}>
            <TouchableOpacity onPress = {handleCaptureImage}>
            <View style = {styles.btn}>
              <Text style = {styles.btnText}>Scaneaza</Text>
            </View>
          </TouchableOpacity>
          </View>
      </View>
    </View>
    </KeyboardWrapper>
  );
};

Короткое видео о проблеме с использованием MRE

Сможете ли вы сделать МРЕ?

async await 15.05.2024 06:23

@asyncawait только что добавил MRE.

Parzival 15.05.2024 06:35

Ссылка на видео гласит: «Это видео не готово. Попросите создателя видео зарегистрироваться и снова поделиться им с вами для предварительного просмотра».

async await 15.05.2024 07:09

@asyncawait загружено на YouTube. Теперь это должно сработать.

Parzival 15.05.2024 07:20
Умерло ли Create-React-App?
Умерло ли Create-React-App?
В этом документальном фильме React.dev мы исследуем, мертв ли Create React App (CRA) и какое будущее ждет этот популярный фреймворк React.
Освоение React Native: Пошаговое руководство для начинающих
Освоение React Native: Пошаговое руководство для начинающих
React Native - это популярный фреймворк с открытым исходным кодом, используемый для разработки мобильных приложений. Он был разработан компанией...
В чем разница между react native и react ?
В чем разница между react native и react ?
React и React Native - два популярных фреймворка для создания пользовательских интерфейсов, но они предназначены для разных платформ. React - это...
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
Хуки React: что это такое и как их использовать
Хуки React: что это такое и как их использовать
Хуки React - это мощная функция библиотеки React, которая позволяет разработчикам использовать состояние и другие возможности React без написания...
0
4
84
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

проблема в handlechange, должно быть так

  const handleChangeEvent = useCallback((name, event ) => {
    setFormData({ ...formData, [name]: event.target.value});
  }, [formData]);
  • проверьте, получают ли параметры имени в handleChangeEvent, если нет, то событие также содержит параметры имени внутри него

Я думаю, вы можете путать TextInput с типом ввода = «текст». TextInput — это собственный компонент, который имеет обработчик событий onChangeText и не возвращает событие в качестве первого аргумента для этого обработчика, а передает сам текст.

async await 15.05.2024 21:48
Ответ принят как подходящий

Я считаю, что повторный рендеринг компонентов — это функция React по умолчанию. Если вам нужен более детальный контроль над повторной визуализацией вашего компонента, вам, вероятно, нужен React.memo. Обертывание компонента в это предотвратит его повторный рендеринг по умолчанию.

const { useState, memo } = React;

const ImgDisplay = memo(({ imgs }) => {
  console.info("rendering ImgDisplay");
  return (
    <div>
      {
        imgs.map((img, i) => <div key = {i}>{img}</div>)
      }
    </div>
  )
})

const Example = () => {
  const [images, setImages] = useState([]);
  const [txt, setTxt] = useState("");

  const captureImage = () => {
    const randomNumberForImagePlaceholder = Math.floor(Math.random() * 100);
    setImages(imgs => [...imgs, randomNumberForImagePlaceholder]);
  };

  return (
    <div>
      <input 
        type = "text"
        onChange = {e => setTxt(e.target.value)}
      />
      <ImgDisplay imgs = {images} />
      <button onClick = {captureImage}>add image</button>
    </div>
  )
};

ReactDOM.createRoot(
  document.getElementById("root")
).render(
  <Example />
);
<div id = "root"></div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

И та же демонстрация, но без заметок, чтобы вы могли видеть журнал, происходящий при изменении ввода.

const { useState, memo } = React;

const ImgDisplay = ({ imgs }) => {
  console.info("rendering ImgDisplay");
  return (
    <div>
      {
        imgs.map((img, i) => <div key = {i}>{img}</div>)
      }
    </div>
  )
};

const Example = () => {
  const [images, setImages] = useState([]);
  const [txt, setTxt] = useState("");

  const captureImage = () => {
    const randomNumberForImagePlaceholder = Math.floor(Math.random() * 100);
    setImages(imgs => [...imgs, randomNumberForImagePlaceholder]);
  };

  return (
    <div>
      <input 
        type = "text"
        onChange = {e => setTxt(e.target.value)}
      />
      <ImgDisplay imgs = {images} />
      <button onClick = {captureImage}>add image</button>
    </div>
  )
};

ReactDOM.createRoot(
  document.getElementById("root")
).render(
  <Example />
);
<div id = "root"></div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

Я просто хотел добавить: если ввод текста не меняет ничего визуально при вводе, вам, вероятно, понадобится useRef вместо состояния. Это также предотвратит повторный рендеринг вашего компонента.

async await 15.05.2024 21:42

Другие вопросы по теме

Приложение аварийно завершает работу при использовании навигации по стеку после обновления с SDK 49 до 51 в React Native Expo
SKD 51: невозможно прочитать свойство NativeModule неопределенного значения
Eslint не показывает мне опцию -> Чтобы проверить синтаксис, найти проблемы и обеспечить соблюдение стиля кода
Почему я получаю ошибку рендеринга (неопределенная ошибка функции) при вызове метода, но свойство в порядке?
Мое приложение React Native вылетает (простая ошибка)
Есть ли способ добавить фоновую музыку без добавления кнопки «Воспроизвести музыку» с помощью Expo AV?
Как сохранить состояние моих компонентов после отмены и повторной визуализации?
Загрузка файла в проект React Native Expo не работает
Как правильно обрабатывать ошибки в функции транзакцииAsync expo-sqlite?
`tsc` продолжает отслеживать `node_modules`. Может ли кто-нибудь помочь мне решить эту проблему?

Похожие вопросы