React Native安卓端PHP修改MySQL后数据更新不同步问题
问题解决:React Native Android端点赞界面状态不同步
问题描述
我开发了一个图片点赞的简易脚本,浏览器端运行正常,能正常更新MySQL数据并展示结果。但在Android端点击爱心按钮时,MySQL中的数据值会正确变更,界面显示却异常:未点赞的图片点击点赞后,MySQL显示已点赞,但Android界面无变化;再次点击点赞,MySQL显示未点赞,Android界面却显示已点赞。
问题根源
- 异步请求未等待:
addLike方法里调用fetch后立刻执行loadData(),此时更新请求还未完成,loadData()拿到的仍是旧数据,导致界面与数据库状态错位。 - 直接修改State:
componentDidMount中直接修改this.state的属性,React无法检测到状态变化,可能引发布局或数据更新异常。 - PHP代码存在错误:
updateLikes.php里有SQL语句引号未闭合、混用JS的console.log、SQL注入风险等问题。
修复代码
1. React Native代码修改
修正addLike方法(等待异步请求完成)
addLike = async (val) => { const formData = new FormData(); formData.append('imageId', val); // 等待更新请求完成后再刷新数据 await fetch('https://projectwebua.000webhostapp.com/updateLikes.php', { body: formData, method: 'POST' }); this.loadData(); };
修正componentDidMount(通过setState修改状态)
componentDidMount() { const handyWidth = this.state.handyWidth; this.setState({ imageOptionsWidth: handyWidth, imageWidth: handyWidth * 0.84, containerOfPicture: handyWidth * 0.96, containerOfPictureInner: handyWidth * 0.92, containerOfPictureInnerMargin: handyWidth * 0.02, descriptionMargin: handyWidth * 0.03, descriptionTextMargin: handyWidth * 0.01, descriptionTextMarginHeart: handyWidth * 0.04, imageOptionsWidthLeft: handyWidth * 0.7, imageOptionsWidthRight: handyWidth * 0.22, containerOfPictureMargin: handyWidth * 0.02 }, () => { // 状态更新完成后再加载数据 this.loadData(); }); }
2. updateLikes.php代码修正(修复语法错误+防SQL注入)
header('Content-Type: application/json; charset=utf-8'); header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: PUT, GET, POST"); $host = "#############"; $user = "#############"; $password = "#############"; $db = "#############"; $conn = mysqli_connect($host, $user, $password, $db); if (!$conn) { die(json_encode(['error' => "Connection failed: " . mysqli_connect_error()])); } // 使用预处理语句避免SQL注入 $imageId = $_POST['imageId']; $sql = "SELECT id, description, likes, source, liked FROM images WHERE id=?"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "i", $imageId); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if (!$result) { echo json_encode(['error' => mysqli_error($conn)]); die(); } $row = mysqli_fetch_assoc($result); $insertLiked = $row['liked'] == "0" ? 1 : 0; $insertLikes = $row['liked'] == "0" ? $row['likes'] + 1 : $row['likes'] - 1; // 预处理更新语句 $sql = "UPDATE images SET likes = ?, liked = ? WHERE id=?"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "iii", $insertLikes, $insertLiked, $row['id']); $updateSuccess = mysqli_stmt_execute($stmt); // 返回更新结果供前端验证 echo json_encode(['success' => $updateSuccess]); mysqli_close($conn);
额外建议
- 给点赞按钮添加加载状态,避免用户重复点击导致多次请求。
- 在
loadData中添加错误处理,捕获网络请求失败的情况。 - 始终使用预处理语句操作数据库,杜绝SQL注入风险。
内容的提问来源于stack exchange,提问作者Andre
相关产品推荐
相关产品推荐

