如何动态渲染React组件?点击按钮新增帖子无法显示问题
问题描述
点击按钮从数据库获取帖子对象并加入数组,需将数组中所有对象渲染为React组件,新增帖子时自动更新列表。使用map()方法后,点击按钮新增的帖子无法显示。
主组件代码
import Post from './Post' import { useState, useEffect, createElement } from 'react' import { useCookies } from 'react-cookie'; import Axios from 'axios' const Content = () => { const [postArr, setPostArr] = useState([]) const getPosts = ()=>{ Axios.defaults.withCredentials = true Axios({ method: 'get', url: 'http://localhost:3010/api/getpost/', headers: {'Content-Type': 'multipart/formdata' } }) .then((response) => { addPostToPostArray(response) }) .catch((response) => { console.log(response); }); } const addPostToPostArray = (response) => { let imgName = response.data.imgurl.slice(68, 999999) let sendObj = { id:response.data.id, posterid:response.data.posterid, imgurl:`http://localhost:3010/images/${imgName}`, title:response.data.title, likes:response.data.likes, date:response.data.date } postArr.push(sendObj) /* A fetched post will look like this: { id:123, posterid:321, imgurl:`http://localhost:3010/images/333.png`, title:'best title', likes:444, date:111111 } */ } return ( <div> {postArr.map((e) => { return <Post post={e}/> })} <button onClick={getPosts}>load post</button> </div> ); } export default Content;
Post组件代码
const Post = (props) => { const post = props.post return ( <div className='post-frame'> <h1>{post.title}</h1> <div className="image-frame"> <img src={post.imgurl}></img> </div> <p>{post.likes}</p> <p>{post.posterid}</p> </div> ); } export default Post;
解决方法
问题核心是直接修改state数组的方式错误:React的state是不可变的,你用postArr.push(sendObj)直接修改原数组,React无法检测到state变化,因此不会触发组件重新渲染,新帖子自然不会显示。
正确做法是通过setPostArr创建新数组更新state,两种常用方式:
方式一:函数式更新(推荐,避免state快照依赖问题)
修改addPostToPostArray函数:
const addPostToPostArray = (response) => { let imgName = response.data.imgurl.slice(68, 999999) let sendObj = { id:response.data.id, posterid:response.data.posterid, imgurl:`http://localhost:3010/images/${imgName}`, title:response.data.title, likes:response.data.likes, date:response.data.date } // 基于之前的state创建新数组 setPostArr(prevPostArr => [...prevPostArr, sendObj]) }
方式二:复制原数组后更新
const addPostToPostArray = (response) => { let imgName = response.data.imgurl.slice(68, 999999) let sendObj = { id:response.data.id, posterid:response.data.posterid, imgurl:`http://localhost:3010/images/${imgName}`, title:response.data.title, likes:response.data.likes, date:response.data.date } // 复制原数组并添加新元素,再更新state const newPostArr = [...postArr] newPostArr.push(sendObj) setPostArr(newPostArr) }
另外注意:请求头里的multipart/formdata拼写错误,应为multipart/form-data,虽不是当前问题的直接原因,但建议修正避免潜在问题。
内容的提问来源于stack exchange,提问作者stefan
相关产品推荐
相关产品推荐

