Повторная выборка из API при нажатии кнопки в React Native

#javascript #reactjs #react-native

#javascript #reactjs #react-native

Вопрос:

Я пытаюсь повторно извлечь новые данные при нажатии кнопки в React Native. Как это сделать?

Это мой текущий код, и он не извлекает новый контент при нажатии кнопки, вместо этого ничего не происходит.

Я делал это до тех пор, пока не извлек содержимое из API, но не могу реализовать обновление при нажатии кнопки, потому что Flatlist не загружается снова и снова.

Заранее спасибо.

 import React, { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, StyleSheet, View, Text, Button } from 'react-native';

import {
  Colors
} from 'react-native/Libraries/NewAppScreen';


const App: () => React$Node = () => {

  
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);


  useEffect(() => {
    fetch('https://exampleapi.dev/')
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, []);


  return (
    <>
    <View style={styles.container}>
      {isLoading ? <ActivityIndicator/> : (
        <FlatList
          data={data}
          keyExtractor={({ id }, index) => id}
          renderItem={({ item }) => (
            <Text style={styles.content}>{item.content}</Text>
          )}
        />
      )}
      
    </View>
     <View style={styles.buttonBottom}> 
    <Button
        title="🔀 Refresh"
        onPress={() => this.FlatList}
        style={styles.buttonShare}
        color="#66BB6A" />
     </View>       
    </>
    
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'space-between',
    backgroundColor: '#1b262c',
    padding: 30,
    flexDirection:'row',
    alignItems:'center'
  },
  FlatList: {
    backgroundColor: Colors.aquamarine,
  },
  content: {
    fontSize: 22,
    textAlign: 'left',
    color: '#bbe1fa'
  },
  buttonBottom: {
    fontSize: 22,
    padding: 10,
    backgroundColor: '#1b262c',
  }
});

export default App;

 

Ответ №1:

Укажите useEffect зависимость, от которой она будет срабатывать при нажатии кнопки.

Добавьте новое состояние, которое будет переключаться при нажатии кнопки:

 const App: () => React$Node = () => {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  const [refetch, setRefetch] = useState(false); // <= this
 

Теперь установите refetch в качестве зависимости значение useEffect :

 useEffect(() => {
    fetch("https://exampleapi.dev/")
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, [refetch]);
 

и, в конце концов, просто переключите состояние refetch :

 <Button
          title="🔀 Refresh"
          onPress={() => setRefetch(!refetch)}
          style={styles.buttonShare}
          color="#66BB6A"
        />
 

Окончательные изменения должны выглядеть следующим образом:

 import React, { useEffect, useState } from "react";
import {
  ActivityIndicator,
  FlatList,
  StyleSheet,
  View,
  Text,
  Button,
} from "react-native";

import { Colors } from "react-native/Libraries/NewAppScreen";

const App: () => React$Node = () => {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  const [refetch, setRefetch] = useState(false);

  useEffect(() => {
    fetch("https://exampleapi.dev/")
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, [refetch]);

  return (
    <>
      <View style={styles.container}>
        {isLoading ? (
          <ActivityIndicator />
        ) : (
          <FlatList
            data={data}
            keyExtractor={({ id }, index) => id}
            renderItem={({ item }) => (
              <Text style={styles.content}>{item.content}</Text>
            )}
          />
        )}
      </View>
      <View style={styles.buttonBottom}>
        <Button
          title="🔀 Refresh"
          onPress={() => setRefetch(!refetch)}
          style={styles.buttonShare}
          color="#66BB6A"
        />
      </View>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "space-between",
    backgroundColor: "#1b262c",
    padding: 30,
    flexDirection: "row",
    alignItems: "center",
  },
  FlatList: {
    backgroundColor: Colors.aquamarine,
  },
  content: {
    fontSize: 22,
    textAlign: "left",
    color: "#bbe1fa",
  },
  buttonBottom: {
    fontSize: 22,
    padding: 10,
    backgroundColor: "#1b262c",
  },
});

export default App;
 

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

1. Ты спас меня. Огромное спасибо.

2. Добро пожаловать, счастливого кодирования. 🙂

Ответ №2:

-> Создать функцию для получения данных из API, например:

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

const getData = ()=>{
    fetch('https://exampleapi.dev/')
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false))
  }
 

-> и когда нажимаете на кнопку, просто вызывайте:

 <Button
          title="🔀 Refresh"
          onPress={getData}
          style={styles.buttonShare}
          color="#66BB6A"
        />