React Native FlatList не сохраняет состояние на модальном - PullRequest
0 голосов
/ 22 апреля 2020

Для контекста я делаю динамическую c форму, в которой пользователь создает свои вопросы и тип каждого вопроса, например, простой текстовый ввод или даже ввод изображения. Список вопросов собран из локальной базы данных SQLite и используется для данных FlatList. Чтобы ответить на вопрос об изображении, я использую модал из модуляact-native-modal. Дело в том, что при показе мод я теряю состояние всех остальных полей, теряя все предыдущие ответы.

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

 function Item({ info, index }) {
    const [resp, setResp] = useState(
      DATA[index].resposta ? DATA[index].resposta : '',
    );
    // controla as respostas de cada pergunta
    useEffect(() => {
      dados[index] = {
        nome_pergunta: info.nome ? info.nome : info.nome_pergunta,
        resposta: resp,
        id_pergunta: info.id_pergunta,
        id_resposta: info.id_resposta ? info.id_resposta : null,
      };
    }, [resp]);
    // caso o input seja do tipo texto
    if (info.tipo === 'text') {
      return (
        <BlocoText>
          <Label>{info.nome}</Label>
          <Input
            //placeholder={info.nome}
            placeholderTextColor="white"
            value={resp}
            onChangeText={value => {
              setResp(value);
            }}
          />
        </BlocoText>
      );
    }
    // caso o input seja do tipo numero
    else if (info.tipo === 'number') {
      return (
        <BlocoText>
          <Label>{info.nome}</Label>
          <Input
            //placeholder={info.nome}
            //placeholderTextColor="white"
            value={resp}
            onChangeText={value => {
              setResp(value);
            }}
            keyboardType="decimal-pad"
          />
        </BlocoText>
      );
    }
    // caso o input seja do tipo multipla escolha
    else if (info.tipo === 'select') {
      const op = info.opcoes.split(',');
      let items = [];
      op.forEach(element => {
        items.push({
          color: '#000',
          key: element.trim(),
          value: element.trim(),
          label: element.trim(),
        });
      });
      return (
        <BlocoText>
          <Label>{info.nome}</Label>
          <BlocoText4>
            <Caixa>
              <RNPickerSelect
                value={resp}
                onValueChange={value => setResp(value)}
                placeholderTextColor="#000"
                placeholder={placeholder}
                useNativeAndroidPickerStyle={true}
                items={items}
              />
            </Caixa>
          </BlocoText4>
        </BlocoText>
      );
    }
    // caso o input seja do tipo file
    else if (info.tipo === 'file') {
      return (
        <BlocoImagem>
          <BotaoImagem
            onPress={() => {
              setOption(index);
              setModalVisible(true);
            }}>
            <Tela2>
              <Label2>{info.nome}</Label2>
            </Tela2>

            <Tela2>
              <Icon
                name="camera"
                size={25}
                color="#FFF"
                styles={{ marginLeft: 50 }}
              />
            </Tela2>
          </BotaoImagem>
          <EnvolveImagem>
            <ImagemCampoNovo
              source={{
                uri: resp
                  ? 'data:image/png;base64,' + resp
                  : 'data:image/png;base64,' + Foto,
              }}
            />
          </EnvolveImagem>
        </BlocoImagem>
      );
    }
    // caso o input seja do tipo data
    else if (info.tipo === 'date') {
      return (
        <BlocoText>
          <Label>{info.nome}</Label>
          <DatePicker
            style={{ width: 295, marginLeft: 9 }}
            date={resp}
            mode="date"
            placeholder="Selecione Uma Data"
            format="DD-MM-YYYY"
            confirmBtnText="Confirm"
            cancelBtnText="Cancel"
            customStyles={{
              dateIcon: {
                position: 'absolute',
                left: 0,
                top: 4,
                marginLeft: 0,
              },
              dateInput: {
                marginLeft: 36,
              },
              // ... You can check the source to find the other keys.
            }}
            onDateChange={date => {
              setResp(date);
            }}
          />
          <Ajusta2 />
        </BlocoText>
      );
    }
  }


А вот код моей модальной камеры:

      <Modal
        transparent={false}
        isVisible={modalVisible}
        style={{ margin: 0 }}
        onBackButtonPress={() => {
          setModalVisible(false);
        }}>
        <View
          style={{
            alignSelf: 'center',
            backgroundColor: '#015',
            alignContent: 'center',
          }}>
          <RNCamera
            ref={ref => setCamera(ref)}
            style={{ flex: 1 }}
            type={RNCamera.Constants.Type.back}
            autoFocus={RNCamera.Constants.AutoFocus.on}
            flashMode={RNCamera.Constants.FlashMode.off}
            androidCameraPermissionOptions={{
              title: 'Permissão para usar a câmera',
              message: 'Precisamos da sua permissão para usar a câmera.',
              buttonPositive: 'Ok',
              buttonNegative: 'Cancelar',
            }}
            captureAudio={false}>
            <View style={{ flex: 5 }} />
            <View style={styles.buttonContainer}>
              <TouchableOpacity onPress={takePicture} style={styles.capture}>
                <Icon name="camera" size={25} color="#7030a0" />
              </TouchableOpacity>
            </View>
          </RNCamera>
        </View>
      </Modal>


Наконец, код the FlatList:

          <Lista
            windowSize={6}
            data={DATA}
            renderItem={({ item }) => (
              <Item info={item} index={DATA.indexOf(item)} />
            )}
            keyExtractor={item => '' + DATA.indexOf(item)}
          />

Я пытался использовать другие методы рендеринга, например, использовать простую функцию array.map для рендеринга элементов, которые не работали, а также пытался найти альтернативу flatlist, так как у меня есть форма на другой странице приложения, но в состоянии stati c, и модал работает, не теряя состояния, но не смог найти хорошее решение.
У меня есть теория, что это может иметь отношение к тому, как я отношусь к изменению входных данных. Может быть, из-за того, что useEffect находится внутри самого Предмета, но я не могу придумать лучшего решения для хранилища данных Dynami c для последующего сохранения.
Я открыт для предложений, даже если это означает, что я не использую FlatList.

* РЕДАКТИРОВАТЬ: Вот несколько закуску к проблеме = https://snack.expo.io/@suxgatov / 7e28c3
Я использую реагировать родной cli в проекте, поэтому некоторые вещи должны были быть удалены для того, чтобы это работало. Например, библиотека камеры не работала, но любой модал имеет такой же результат, поэтому это не меняет проблему.

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