【问题标题】:I would like to know how I can update the like (heart) based on the id我想知道如何根据 id 更新like (heart)
【发布时间】:2022-01-04 00:56:36
【问题描述】:

在代码中,我有三个“帖子”(卡片),我想分别为三个帖子处理点赞按钮(心)。 第一个帖子(顶部卡片)的 ID 为 1,第二个帖子的 ID 为 2,第三个帖子的 ID 为 3。现在,所有三张卡片的状态都相同,我应该并且可以为每张卡片创建一个状态吗?

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, View, SafeAreaView, ScrollView} from 'react-native';
import {useState} from 'react';
import Card from './components/card';

export default function App() {

  const [liked, setLiked] = useState();
  
  function onPicLike(id)
  {
    alert(id);

    if(liked){
      setLiked(false);
    } else
    setLiked(true);
  };

  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.body}>
        <Card image={require('./assets/picture1.png')} liked={liked} id={1} onLike={onPicLike}/>
        <Card image={require('./assets/picture2.png')} liked={liked} id={2} onLike={onPicLike}/>
        <Card image={require('./assets/picture3.png')} liked={liked} id={3} onLike={onPicLike}/>
      </ScrollView>
      <StatusBar style="auto" />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: Platform.OS === "android" ? 30 : StatusBar.currentHeight,
    backgroundColor: '#D0CEE2'
  },
  body: {
    flex: 1,
    backgroundColor: 'lightgray'
  }
});
import { StyleSheet, Text, View, SafeAreaView, Image, TouchableOpacity} from 'react-native';
import { FontAwesome } from '@expo/vector-icons';
import { TouchableWithoutFeedback } from 'react-native-web';

export default function Card({image, liked, id, onLike}) {

    console.log(liked);

  return (
        <View style={styles.card}>
          <View style={{justifyContent: 'center', alignItems: 'center'}}>
            <TouchableWithoutFeedback onLongPress={() =>onLike(id)}>
                <Image source={image} style={{width: 50, height: 50, resizeMode: 'contain', borderRadius: 20}}/>
            </TouchableWithoutFeedback>
          </View>
          <View style={styles.footer}>
            <Text style={[{ flex: 1}, styles.actionButtons]}>
              Comment
            </Text>
            <Text style={[styles.actionButtons, {marginRight: 5}]}>
              Like
            </Text>
            <TouchableOpacity onPress={() =>onLike(id)}>
                <FontAwesome name="heart" size={16} color={liked ? "red" : "grey"} />
            </TouchableOpacity>
          </View>
        </View>
  );
}

const styles = StyleSheet.create({
  card: {
    backgroundColor: 'white',
    marginHorizontal: 50, 
    minHeight: 100, 
    borderRadius: 10, 
    marginVertical: 30,
    padding: 10,
  },
  footer: {
    flexDirection: 'row',
    alignItems: 'center',
    flex: 1,
    paddingTop: 10
  },
  actionButtons: {
    fontSize: 16
  }
});

【问题讨论】:

  • 类似这样的东西:&lt;Card ... onLike={() =&gt; onPicLike(1)} /&gt;。在liked 状态下,您拥有一个结构,例如一个数组,每张卡片的真/假:[false, true, false] - 喜欢第二个

标签: reactjs react-native react-hooks


【解决方案1】:

您可以通过两种方法来管理它 - 第一个使用一般状态保存三张卡片的状态并将其传递给卡片

   const [liked, setLiked] = useState({
    1:false,
    2:false,
    3:false
    });
      
      function onPicLike(id)
      {
        alert(id);
          setLiked(prevState=>({...prevState,[id]:!prevState[id]}));
        
      };  
    ......
     <Card image={require('./assets/picture1.png')} liked={liked[1]} id={1} onLike={onPicLike}/>
<Card image={require('./assets/picture1.png')} liked={liked[2]} id={2} onLike={onPicLike}/>
.....
  • 第二种方法是管理其组件中的每个卡片状态,因此您不需要传递 onPickLike 函数或喜欢的状态。

    export default function Card({image,  id}) {
     const [liked,setLiked] = useState(false) 
       return (
             <View style={styles.card}>
               <View style={{justifyContent: 'center', alignItems: 'center'}}>
                 <TouchableWithoutFeedback onLongPress={() =>setLiked(!liked)}>
                     <Image source={image} style={{width: 50, height: 50, resizeMode: 'contain', borderRadius: 20}}/>
                 </TouchableWithoutFeedback>
               </View>
               <View style={styles.footer}>
                 <Text style={[{ flex: 1}, styles.actionButtons]}>
                   Comment
                 </Text>
                 <Text style={[styles.actionButtons, {marginRight: 5}]}>
                   Like
                 </Text>
                 <TouchableOpacity onPress={() =>setLiked(!liked)}>
                     <FontAwesome name="heart" size={16} color={liked ? "red" : "grey"} />
                 </TouchableOpacity>
               </View>
             </View>
       );
     }
    

【讨论】:

  • 非常感谢!第二种方法效果很好,没有考虑到这一点。我想选项一更干净,但我无法让它工作,我无法真正解释为什么它不起作用,因为我对原生反应有点陌生,我无法向自己解释什么是“setLiked(prevState=> ({...prevState,id:!prevState[id]}));"是的。
  • 第一个没有用,因为我忘记像 [id] 那样将 id 包装在 setLiked 中,所以函数将是 code function onPicLike(id) { alert(id); setLiked(prevState=>({...prevState,[id]:!prevState[id]})); }; code 我编辑了第一种方法,它现在可以工作了.. 对于 setLiked,您可以传递以前的状态以对其进行一些操作,然后返回新状态,我所做的我谈到了以前的状态并反转了 id 状态从假到真,从真到假检查 React Hooks,事情会变得更容易
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2019-05-20
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
相关资源
最近更新 更多