【问题标题】:How do I update an item that was passed to a function?如何更新传递给函数的项目?
【发布时间】:2019-01-23 11:43:24
【问题描述】:

我正在尝试通过添加 + 1 来更新项目,而不让 fetch 更新项目。基本上,当我fetch 时,后端将数字更新为 + 1,而不是那样做,我想通过前端来做。

<TouchableOpacity
  onPress={() => this.anim_like(item)} <-- Passing all items from dataSource
  style={{position:'absolute',  height: '100%', width: '100%', right: 140, bottom: 50}}
>
  <Animation
    progress={item.progress}
    source={require('../Animations/favourite_app_icon.json')}
    style={{ height: '100%', width: '100%', position: 'absolute'}}
    resizeMode={`contain`}
   />
</TouchableOpacity>
<Text>{item.likes}</Text> <-- Getting likes from the fetched data




anim_like = (item) => {
  Animated.timing(item.progress, {
    toValue: 1,
    duration: 1500,
    easing: Easing.linear,
  }).start();
  fetch(`https://www.example.com/React/user-like.php`, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      post_id : item.id,
    })  
  }).then((response) => response.json())
    .then((responseJson) => {
      //this.refetchData(); <-- Current way to update item.likes
      item.likes = item.likes + 1;<-- Want to update it this way by + 1 without updating the full fetch data
    }).catch((error) => {   
  });
}

当然,anim_like 一旦点击,就会在后端添加 + 1。我目前拥有的方式是,一旦它在后端更新,重新获取结果并显示它。这会导致响应时间变慢。

这里是获取 api:

fetch(`https://www.example.com/React/user.php` , {
   method: 'POST',
   headers: {
     'Accept': 'application/json',
     'Content-Type': 'application/json',
   }

  })
    .then((response) => response.json())
    .then((responseJson) => {
      this.setState({
        user_image:  responseJson[0].user_images.map(item => ({ ...item, progress: new Animated.Value(0)})) <-- This adds a unique animated.value to each user 
        },function() {

        });
    })
    .catch((error) => {
      //console.error(error);
    });

我使用this.state.user_image 从后端检索所有现有数据并将其放入renderItem 中的Flatlist。我显示我想要的数据,例如上面的代码,item.likesitem.progress

它还负责将其转换为 JSON 数组并使用 React Native 中的数据:

[{
  "food":"pizza",
  "who":"Person",
  "user_images":[{
    "id":"114",
    "username":"Hannah_L123",
    "images":"resized_1522-20131219-creativity.jpg",
    "date":"12\/04\/2017",
    "likes": "20"
  }]
}]

如果其中有任何令人困惑的地方,我很乐意为它提供一些启示!谢谢!

【问题讨论】:

  • 所以基本上你想在得到后端响应之前加1?
  • @bwalshy 好吧,加 1 而没有得到后端的响应。相反,前端将显示该响应,这应该消除调用另一个 fetch 的额外步骤。
  • 听起来你可以在重新获取之前增加你的状态,当你得到重新获取的响应时,你可以检查它是否与前端显示的数字相对应。
  • @LaneyWilliams 我认为来自后端的帖子散文应该返回最后一个计数,这样您就可以从后端返回的数据中设置新状态而无需获取类似内容
  • 您的代码中的refetchData() 在哪里?你能用它更新你的问题吗?

标签: json reactjs react-native fetch jsx


【解决方案1】:

我相信您想在不更新服务器的情况下更新喜欢。

您可以通过以下方式实现:

在你的类中创建一个状态。

constructor(props){
    super(props)
    this.state = {
        animLike: ''
    }
}

将事件更改为:

onPress={this.updateApi}

原来是这样。

<TouchableOpacity
    onPress={this.updateApi} //<-- Passing like to
    style={{position:'absolute',  height: '100%', width: '100%', right: 140, bottom: 50}}>
        <Animation
            progress={item.progress}
            source={require('../Animations/favourite_app_icon.json')}
            style={{ height: '100%', width: '100%', position: 'absolute'}}
            resizeMode={`contain`}
        />
</TouchableOpacity>
<Text>{this.state.animLike}</Text> // <--Getting likes from state

在你的类中添加一个函数来更新前端和后端

updateApi = () =>{
    this.setState({animLike:+1})
    this.anim_like(this.state.animLike)
}

【讨论】:

  • 谢谢,但{this.state.animLike} 不会有来自 JSON 的当前“点赞”,并且不会在后端更新
  • @SgGHaleb 有没有办法可以在使用 {item.likes} 而不是 {this.state.animLike} 的同时执行此方法?只是它是空白的,{item.likes} 显示当前的点赞数。
  • 实际上,如果我可以从 json 数组中获取所有喜欢并将其置于状态,则此代码可以工作,但我该怎么做呢?
  • 将此添加到您的获取响应this.setState({ animLike: responseJson[0].user_images.likes) },但我认为这将带您回到第一个问题。
  • 是的...responseJson[0].user_images.likes 未定义,所以我修改为:responseJson[0].user_images[0].likes。但这确实控制台记录了所有的喜欢,只有一个。我为这一切道歉。确实,我设置它的原因是一个更好的方法,但是获取响应很慢。
【解决方案2】:

如果item 处于您的状态,您可以像这样更新它

//where you do item.likes = item.likes +1  you Must do
this.setState(prevState => ({
    item: {
        ...prevState.item,
        likes: prevState.item.likes + 1
    }
}));

如果它在像ˋthis.state.itemspassed rendered byrenderItem`这样的数组中,那么你可以

//where you call anim_like you have to pass the index of the item like
this.anim_like(item, index)

//in your anim_like function where you do item.likes = item.likes + 1 you must do
let items = this.state.items; // to take the items and manipulate it
item.likes = item.likes + 1; //update likes for the current item
items[index] = item; // update the item in the array with the index passed in parameter of anim_like
this.setState({
    items
}); // update the state to have your screen refresh 

但我建议为具有适当方法的项目使用专用组件,例如 anim_like,因为这样它会重新渲染所有屏幕,而不仅仅是喜欢的组件。

在你的情况下,我认为this.state.itemsthis.state.user_image

【讨论】:

  • 非常感谢,但这是我得到的错误:TypeError: undefined is not an object(evaluating 'prevState.item.likes' )
  • @LaneyWilliams 尝试我的第二种方法,但在您的情况下,您的状态似乎不是items,而是user_image,因此您必须使我的代码适应您的。
  • 是的,如果我可以从 json 数组中获得所有喜欢的内容并将其置于状态中,那会更容易。问题中我上面的当前代码可能吗?
  • 我明白了。我的意思是我设置它的旧方法有效,但是获取响应时间太慢了。我可以通过这样做得到喜欢:responseJson[0].user_images[0].likes,但它并没有得到所有的喜欢。
  • 你在执行 fetch 之前增加喜欢,如果发生错误或错误,你可能会在你的 catch 语句中减少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
  • 2012-07-23
  • 2015-12-14
  • 2021-11-21
相关资源
最近更新 更多