mrkkrly
mrkkrly

Reputation: 35

How to refresh a single item in a FlatList in React-Native?

I made a Like function with React and Flask API, it works pretty well, it makes the Like action but it only appears when I refresh the whole list. Somehow I want to refresh the Like picture and the Like count at the post.

I tried to put extraData in my FlatList but that does not solve my problem...

handleClick() {
    const headers = {
      'Authorization': 'jwt ' + this.props.jwt
    };
    const action = this.props.has_liked?  'unlike':'like' 
    axios.post("http://127.0.0.1:5000/API/likeaction",{
        id: this.props.id,
        action: action
    }, {
      headers: headers
    })
    .then((response) => {
      console.log(response.data);
    })
    .catch((error) => {
      console.log(error)
    });
    this.setState({liked: action})
  }
    render() {
      const img = this.props.has_liked?  require('../assets/icons/heart-filled.png') : require('../assets/icons/heart-no-fill.png') 
        return(
        <View style={{flex:1, marginTop: 10, marginBottom:16, left: 20}}>
         <View style={{flex: 1, flexDirection: 'row'}}> 
         <Image source={this.props.image_uri} style={{height:42, width: 42, borderRadius:21}}/>
          <Text style={{left:20,paddingTop:6}}>{this.props.author}</Text>
          <Text style={{position: 'absolute', right: 40, paddingTop:6,fontSize:12,color:'#babbbc'}}> {this.props.date} </Text>
         </View>
        <View style={{flex:1, left: 60, right:20,width: '70%', marginTop:-10}}>
          <Text style={{fontWeight:'bold',fontSize:18,marginBottom:6}}>{this.props.title} </Text>
          <Text style={{fontSize:16,marginBottom:6 }}>{this.props.content}</Text>
        <View style={{flex: 1, flexDirection: 'row'}}>
          <TouchableOpacity onPress={this.handleClick}>
          <Image style={{width:24, height:24, marginBottom:6, marginTop:6}} source={img} />
          </TouchableOpacity>
          <Text style={{paddingTop:10, marginLeft:6, fontSize:14,color:'#bfbfbf'}}>{this.props.likes}</Text>
        </View>
        </View>
      </View>
      );
    }

  }
<FlatList
            data={this.state.dataSource}
            extraData={this.state}
            renderItem={({item}) => <PostView title={item.title}
                                        content={item.content}
                                        author={item.author} 
                                        date={item.date_posted} 
                                        likes={item.likes} 
                                        has_liked={item.has_liked}
                                        jwt = {this.props.screenProps.jwt}
                                        id = {item.id}
                                        image_uri={{uri:'http://127.0.0.1:5000/static/profile_pics/'+item.profile_image}}/> }
                                        refreshing={this.state.refreshing}
                                        onRefresh={this.handleRefresh}
                                        keyExtractor={item => item.id}/>
        </View>

Upvotes: 0

Views: 726

Answers (2)

Kamal Pandey
Kamal Pandey

Reputation: 1596

try with in home

this.state = {
        loading: true,
        email: '',
        error: '',
        refreshing: false,
        dataSource: [],
        updated: false
      }



handleChange = () => {
    this.setState({ updated: true })
    }



handleRefresh = () => {
 this.setState({
   refreshing: true,
   data: this.state.dataSource
  }, () => {
    this.makeRemoteRequest()
   })
        }

Replace

<PostView title={item.title}
.... 
/>

with

<PostView title={item.title}
    .....
    handleChange={this.handleChange}/>






    extraData={this.state}

and update 

and

  handleClick() {
    const headers = {
      'Authorization': 'jwt ' + this.props.jwt
    };
    axios.post("http://127.0.0.1:5000/API/likeaction",{
        id: this.props.id,
    }, {
      headers: headers
    })
    .then((response) => {
      console.log(response.data);
      if(response.data.account == "liked"){
        this.setState({liked:true})
      }else{
        this.setState({liked:false})
      }
    })
    .catch((error) => {
      console.log(error)
    });
  }

with

handleClick() {
    const headers = {
      'Authorization': 'jwt ' + this.props.jwt
    };
    axios.post("http://127.0.0.1:5000/API/likeaction",{
        id: this.props.id,
    }, {
      headers: headers
    })
    .then((response) => {
      console.log(response.data);
      this.props.handleChange(true);
      if(response.data.account == "liked"){
        this.setState({liked:true})
      }else{
        this.setState({liked:false})
      }
    })
    .catch((error) => {
      console.log(error)
    });
  }


const img = this.state.liked?  require('../assets/icons/heart-filled.png') : require('../assets/icons/heart-no-fill.png') 

with

const img = this.state.liked ?  require('../assets/icons/heart-filled.png') : require('../assets/icons/heart-no-fill.png') 

Upvotes: 0

Idan
Idan

Reputation: 4023

extraData :

extraData={{this.state}}

and put this.setState({liked: action}) here:

.then((response) => {
      console.log(response.data);
      this.setState({liked: action})
    })

Upvotes: 1

Related Questions