简体   繁体   中英

Making a function, call it with button click and update the view with results in react native

UPDATED CODE

  • This now fetches the data when button clicked but I cant display it as it did when it loaded first time?

I am totally new with react native so I am sorry if I explain my problem wrong or seem a little thick. I have made a screen that fetches data and displays the data and it seems to work quite well. However I have a couple of buttons and I want to add an onclick to call a function.

Maybe I am getting this wrong but its supposed to work like javascript which I have no problem with but I think I am missing something with the difference between components and functions.

For example in my code its just automatically fetches the data and displays it. How would I make functions to load the data when one the buttons is clicked and also update the view with the new loaded data?

I have tried putting the functions in with the fetch data but I seem to have to add everything but surely I can make re-usable functions for each task like I would in javascript.

I have included my code for the page and also what I have tried. Any help of advice would be great as when I am researching on the.net I get confused information between reactjs and native.

Also all the code below has been snippets taken from various places and played around with so it is totally probably all wrong in terms of structure.

The code:

import React from "react";
import {
StyleSheet,
View,
ActivityIndicator,
FlatList,
Text,
StatusBar,
Image,
TouchableOpacity,
ScrollView,
SafeAreaView
} from "react-native";
import Icon from "react-native-vector-icons/Entypo";
import CupertinoButtonPurple1 from "../components/CupertinoButtonPurple1";
import Removebutton from "../components/removebutton";


export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
dataSource:[] };
}
componentDidMount(){
fetch("https://www.uberfantasies.com/testv2.php")
.then(response => response.json())
.then((responseData)=> {
this.setState({
loading: false,
dataSource: responseData.data
})
})
.catch(error=>console.log(error)) //to catch the errors if any
}
FlatListItemSeparator = () => {
return (

<View/>
);
}
renderItem=(data)=>


<SafeAreaView>
 <View style={styles.container}>
      <View style={styles.rect}>
        <View style={styles.imageRow}>
          <Image source={{uri: data.item.image}} style={styles.image} />
          <View style={styles.group2Column}>
            <View style={styles.group2}>
              <Text style={styles.bitch}>
              <Text>{data.item.from} sent you a mesage!</Text>
              </Text>
              <Text style={styles.loremIpsum}>
                &quot;{data.item.message}&quot;
              </Text>
            </View>
            <View style={styles.loremIpsum2Row}>
              <Text style={styles.loremIpsum2}>{data.item.when}</Text>
              <View style={styles.loremIpsum2Filler}></View>
              <View style={styles.group3}>
                <CupertinoButtonPurple1
                  style={styles.cupertinoButtonPurple1}
                ></CupertinoButtonPurple1>
                <Removebutton
                  style={styles.removebutton}
                ></Removebutton>
              </View>
            </View>
          </View>
        </View>
      </View>
    </View>
</SafeAreaView>

render(){
if(this.state.loading){
return(
<View style={styles.loader}>
<ActivityIndicator size="large" color="#0c9"/>
</View>
)}
return(
<View style={styles.container}>

<FlatList
data= {this.state.dataSource}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem= {item=> this.renderItem(item)}
keyExtractor= {item=>item.id.toString()}
/>

</View>
)}
}
const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  loader:{
  flex: 1,
  justifyContent: "center",
  alignItems: "center",
  backgroundColor: "#fff"
  },
  rect: {
    height: 97,
    backgroundColor: "rgba(230,230, 230,0.57)",
    borderWidth: 0,
    borderColor: "rgba(0,0,0,0.57)",
    marginTop: 0,
    borderBottomWidth: 1,
borderBottomColor: "#d5d5d5",
backgroundColor: "#f4f4f4"
  },
  image: {
    width: 80,
    height: 80,
        borderRadius: 15,
    borderWidth:  4,
    borderColor: '#ffffff',
    shadowColor: '#d5d5d5',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.8,
    shadowRadius: 2
  },
  group2: {
   
    height: 41
  },
  bitch: {
    fontFamily: "sans-serif-condensed",
    color: "#121212",
    fontSize: 14,
    height: 17,
    fontWeight: "bold",
    marginTop: 2
  },
  loremIpsum: {
    fontFamily: "sans-serif-condensed",
    color: "#121212",
    height: 17,
    width: 159,
    marginTop: 4
  },
  loremIpsum2: {
    fontFamily: "sans-serif-condensed",
    color: "#121212",
    fontSize: 10,
    marginTop: 8
  },
  loremIpsum2Filler: {
    flex: 1,
    flexDirection: "row"
  },
  group3: {
    width: 125,
    height: 26,
    
    flexDirection: "row",
    justifyContent: "space-between",
    marginRight: 25
  },
  cupertinoButtonPurple1: {
    height: 25,
    width: 57
  },
  cupertinoButtonDanger2: {
    height: 25,
    width: 57
  },
  loremIpsum2Row: {
    height: 26,
    flexDirection: "row",
    marginTop: 17,
    marginRight: 33,
    width: "100%"
  },
  group2Column: {
    width: 275,
    marginLeft: 16
  },
  imageRow: {
    height: 84,
    flexDirection: "row",
    marginTop: 8,
    marginLeft: 4
  }
});

and the way I have tried to make a function and the way I think it should work with results?

The UPDATED code that fetches data but I cant get it to display data how it did in the previous code? Going out my nut here because I think Im missing something silly. If I had only one element to display or change I could do it but I think its because it looks through the results? Am i wrong?

Heres the code:

import React, { useState, Component } from 'react'
import {
StyleSheet,
View,
ActivityIndicator,
FlatList,
Text,
StatusBar,
Image,
TouchableOpacity,
ScrollView,
SafeAreaView
} from 'react-native'
class App extends Component {
  state = {
    loading: true,
    dataSource:[],
    Status: "Not loaded"
  }

  onPress = () => {

fetch("https://www.uberfantasies.com/testv.php")
.then(response => response.json())
.then((responseData)=> {

this.setState({
loading: false,
Status: "Loaded",
dataSource: responseData.data
}) 

console.log(this.state.dataSource)
})

.catch(error=>console.log(error)) //to catch the errors if any

}

 render() {
   
    return (
      <View style={styles.container}>
        <TouchableOpacity
         style={styles.button}
         onPress={this.onPress}
        >
         <Text>Click me</Text>
        </TouchableOpacity>
        <View>
          <Text>
            Status : { this.state.Status }
          </Text>
        </View>
      </View>
    )
  }
}



const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  button: {
    alignItems: 'center',
    backgroundColor: '#DDDDDD',
    padding: 10,
    marginBottom: 10
  },
  loader:{
  flex: 1,
  justifyContent: "center",
  alignItems: "center",
  backgroundColor: "#fff"
  }
})

export default App;

if you want to call a function within onPress you need to call it. Like

<Button title="Press Me" onPress={() => ReloadData()} />

Below is a sample code snippet. I have used the function component as it is easy for a beginner. Assuming your output of the API call is a list, I am setting it to the state variable. SO whenever the 'apiData' variable value changes your component will re-render. You can user either a button or a touchable wrapper component for a clickable item.

const [apiData, setApiData] = useState([]);

const MySampleComponent = () => {
  const apiCall = () => {
    //Your code
     setApiData(result);

  };
  const renderListItem = (itemData) => <Text>{itemData.item.<your key>}</Text>;
  return (
    <View>
      <FlatList
        keyExtractor={item => item.id}
        data={apiData}
        renderItem={renderListItem}
      />
      <Button onPress={apiCall} />
      <TouchableOpacity onPress={apiCall}>
          <Text>Click Me</Text>
      </TouchableOpacity>
    </View>
  );
};

Thanks for your comments and help, I think I have a much better way of understanding a few things now. I have managed to get a load button to fetch data and display it in the way as previously managed. I know it does not look like much progress but trust me this is a big step to getting to grips with the way things work for me.

Now time to play around with it, thanks again.

The working code (well best I can do at the minute!)

import React, { useState, Component } from 'react';
import {
  StyleSheet,
  View,
  ActivityIndicator,
  FlatList,
  Text,
  StatusBar,
  Image,
  TouchableOpacity,
  ScrollView,
  SafeAreaView,
} from 'react-native';

import Icon from 'react-native-vector-icons/Entypo';
import CupertinoButtonPurple1 from '../components/CupertinoButtonPurple1';
import CupertinoButtonDanger2 from '../components/CupertinoButtonDanger2';

class App extends Component {
  state = {
    loading: false,
    dataSource: [],
    Status: 'Not loaded',
  };

  componentDidMount() {
    //  this.onPress();
  }

  onPress = () => {
    this.setState({
      loading: true,
    });

    fetch('https://www.uberfantasies.com/testv.php')
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          loading: false,
          Status: 'Loaded',
          dataSource: responseData.data,
        });

        console.log(this.state.dataSource);
      })

      .catch((error) => console.log(error)); //to catch the errors if any
  };
  FlatListItemSeparator = () => {
    return <View />;
  };
  renderItem = (data) => (
    <SafeAreaView>
      <View style={styles.container}>
        <View style={styles.rect}>
          <View style={styles.imageRow}>
            <Image source={{ uri: data.item.image }} style={styles.image} />
            <View style={styles.group2Column}>
              <View style={styles.group2}>
                <Text style={styles.bitch}>
                  Bitch from Cov sent you a mesage!
                </Text>
                <Text style={styles.loremIpsum}>
                  &quot;Hi there you Sexy Beast!&quot;
                </Text>
              </View>
              <View style={styles.loremIpsum2Row}>
                <Text style={styles.loremIpsum2}>12 Feb 2022, 6.05 pm</Text>
                <View style={styles.loremIpsum2Filler}></View>
                <View style={styles.group3}>
                  <CupertinoButtonPurple1
                    style={
                      styles.cupertinoButtonPurple1
                    }></CupertinoButtonPurple1>
                  <CupertinoButtonDanger2
                    style={
                      styles.cupertinoButtonDanger2
                    }></CupertinoButtonDanger2>
                </View>
              </View>
            </View>
          </View>
        </View>
      </View>
    </SafeAreaView>
  );

  render() {
    if (this.state.loading) {
      return (
        <View style={styles.loader}>
          <ActivityIndicator size="large" color="#0c9" />
        </View>
      );
    }
    return (
      <View style={styles.container}>
        <TouchableOpacity style={styles.button} onPress={this.onPress}>
          <Text>Click me</Text>
        </TouchableOpacity>
        <View>
          <Text>Status : {this.state.Status}</Text>
        </View>

        <FlatList
          data={this.state.dataSource}
          ItemSeparatorComponent={this.FlatListItemSeparator}
          renderItem={(item) => this.renderItem(item)}
          keyExtractor={(item) => item.id.toString()}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  button: {
    alignItems: 'center',
    backgroundColor: '#DDDDDD',
    padding: 10,
    marginBottom: 10,
  },
  loader: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
  },
  rect: {
    height: 97,
    backgroundColor: 'rgba(230,230, 230,0.57)',
    borderWidth: 0,
    borderColor: 'rgba(0,0,0,0.57)',
    marginTop: 0,
    borderBottomWidth: 1,
    borderBottomColor: '#d5d5d5',
    backgroundColor: '#f4f4f4',
  },
  image: {
    width: 80,
    height: 80,
    borderRadius: 15,
    borderWidth: 4,
    borderColor: '#ffffff',
    boxShadow: '0px 2px 4px 0px rgb(0 0 0 / 55%)',
  },
  group2: {
    width: 275,
    height: 41,
  },
  bitch: {
    fontFamily: '-apple-system,Segoe UI,Roboto,sans-serif',
    color: '#121212',
    fontSize: 14,
    height: 17,
    fontWeight: 'bold',
    marginTop: 2,
  },
  loremIpsum: {
    fontFamily: '-apple-system,Segoe UI,Roboto,sans-serif',
    color: '#121212',
    height: 17,
    width: 159,
    marginTop: 4,
  },
  loremIpsum2: {
    fontFamily: '-apple-system,Segoe UI,Roboto,sans-serif',
    color: '#121212',
    fontSize: 10,
    marginTop: 8,
  },
  loremIpsum2Filler: {
    flex: 1,
    flexDirection: 'row',
  },
  group3: {
    width: 121,
    height: 26,
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  cupertinoButtonPurple1: {
    height: 25,
    width: 57,
  },
  cupertinoButtonDanger2: {
    height: 25,
    width: 57,
  },
  loremIpsum2Row: {
    height: 26,
    flexDirection: 'row',
    marginTop: 17,
    marginRight: 3,
  },
  group2Column: {
    width: 275,
    marginLeft: 16,
  },
  imageRow: {
    height: 84,
    flexDirection: 'row',
    marginTop: 8,
    marginLeft: 4,
  },
});

export default App;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM