我的应用程序上的新帖子未显示,但旧帖子显示。反应
New posts on my app are not showing but the old posts are. React
我最近在我的社交媒体应用程序中添加了 redux。旧的 posts(在我添加 redux 之前存在的那些)正在正确呈现,但是当我尝试添加新的 post 时,它只显示一张空白卡片。我检查了 redux 存储和所有内容,数据存储正确。
This is the redux state before I add a new post. You can see the old posts(The ones that were there before I added redux to my project)
This is after I add a new post. The data is correctly added to the redux store but all it shows is a blank card on the webpage
这是负责呈现 post 的代码。
class PostComment extends Component{
state={
showNewPost: false
}
componentDidMount() {
this.props.onFetchPosts();
}
DeleteCommentHandler = (index) => {
this.props.onDeletePost(index);
}
ShowFunction = () => {
this.setState({showNewPost: !this.state.showNewPost})
}
render() {
let cardData = <center> <Spinner/></center>
if(!this.props.loading){
cardData = <div className="posts">
{/*add font awesome search icon*/}
<div className="topSection">
<input type="text" className="Searchbar" placeholder="Search for people, topics or keywords..."/>
<Button className="btn btn-primary">Search</Button>
<NewPost/>
</div>
{this.props.data.reverse().map((res) => (
<div>
<Card
key={res.id}
className="Cards"
>
<Card.Body
className="container">
<h6>
@ANONYMOUS
</h6>
<Card.Text>
{res.Comment}
</Card.Text>
<div>
<center>
<img src={res.ImageUrl} width = "680px" height="390px" />
</center>
</div>
<br/>
<Button className="btn btn-danger"
style={{float:"right", width:"35px", height:"35px", borderRadius:"5px"}}
onClick={() => this.DeleteCommentHandler(res.id)}>
<center>
<FontAwesomeIcon icon={faTrash} style={{width:"11px"}}/>
</center>
</Button>
</Card.Body>
<Card.Footer style={{position:"relative", marginTop:"20px"}}>
{res.Date}
</Card.Footer>
</Card>
</div>
)
)}
</div>
}
return(
<div>
{cardData}
</div>
);
}
}
const mapStateToProps = state => {
return {
data: state.Data,
loading: state.loading
};
};
const mapDispatchToProps = dispatch => {
return {
onFetchPosts: () => dispatch(actions.FetchPost()),
onDeletePost: (postId) => dispatch(actions.DeletePost(postId))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(PostComment);
这是 action.js 文件
import axios from '../../axios-comments';
import * as actionTypes from './actionTypes';
export const NewPostSuccess = (id, postData) => {
return {
type: actionTypes.New_Post_Success,
payload: {
data: postData,
id: id
}
}
}
export const NewPostError = (error) => {
return {
type: actionTypes.New_Post_Error,
error: error
}
}
export const NewPost = (postData) => {
return (dispatch) => {
axios.post('/Data.json', postData)
.then(response => {
console.log(response.data);
dispatch(NewPostSuccess(response.data.name, postData));
})
.catch(error => {
dispatch(NewPostError(error));
})
}
}
export const DeletePostSuccess = (id) => {
return {
type: actionTypes.Delete_Post_Success,
index: id
}
}
export const DeletePost = (index) => {
return (dispatch) => {
axios.delete('/Data/'+ index + '.json')
.then(response => {
console.log(response.data);
dispatch(DeletePostSuccess(index))
})
}
}
export const FetchPostStart = () => {
return {
type: actionTypes.Fetch_Post_Start
};
};
export const FetchPostSuccess = (fetchedData) => {
return {
type: actionTypes.Fetch_Post_Success,
payload: fetchedData
}
}
export const FetchPostError = (error) => {
return {
type: actionTypes.Fetch_Post_Error,
error: error
}
}
export const FetchPost = () => {
return dispatch => {
dispatch(FetchPostStart());
axios.get('/Data.json')
.then(response => {
const fetchedData = [];
for(let key in response.data){
fetchedData.push({
...response.data[key],
id: key
});
}
dispatch(FetchPostSuccess(fetchedData));
})
.catch(error => {
dispatch(FetchPostError(error));
});
}
}
这是reducer函数
import * as actionTypes from '../actions/actionTypes';
const initialState = {
Data: [],
loading: false
}
const reducer = (state = initialState, action) => {
switch(action.type){
case actionTypes.New_Post_Error:
return {
...state,
loading:false
}
case actionTypes.New_Post_Success:
return {
...state,
loading: false,
Data: [...state.Data, action.payload.data]
}
case actionTypes.Delete_Post_Success:
const selectedComment = state.Data.filter(res => res.id !== action.index);
return {
...state,
loading: false,
Data: selectedComment
}
case actionTypes.Fetch_Post_Start:
return {
...state,
loading:true
}
case actionTypes.Fetch_Post_Error:
return {
...state,
loading:false
}
case actionTypes.Fetch_Post_Success:
return {
...state,
loading: false,
Data: action.payload
}
default: return state;
}
}
export default reducer;
非常感谢
据我所知,是的,您填充了 state.Data
,但请注意在旧对象中您的 属性 键是 PascalCased 而不是像新添加的 post 对象那样的驼峰式.
vs
在您的代码中,您正在映射 res.Comment
和 res.ImageUrl
!
虽然我强烈建议您采用更标准的 pascalCased 命名约定(可能从您的 JSON 数据中的源开始!!),但您可以更新新的 post 成功减速器案例以保持状态不变。
case actionTypes.New_Post_Success:
const { comment: Comment, imageUrl: ImageUrl } = action.payload.data;
return {
...state,
loading: false,
Data: [
...state.Data,
{ Comment, ImageUrl },
],
}
我最近在我的社交媒体应用程序中添加了 redux。旧的 posts(在我添加 redux 之前存在的那些)正在正确呈现,但是当我尝试添加新的 post 时,它只显示一张空白卡片。我检查了 redux 存储和所有内容,数据存储正确。 This is the redux state before I add a new post. You can see the old posts(The ones that were there before I added redux to my project)
This is after I add a new post. The data is correctly added to the redux store but all it shows is a blank card on the webpage
这是负责呈现 post 的代码。
class PostComment extends Component{
state={
showNewPost: false
}
componentDidMount() {
this.props.onFetchPosts();
}
DeleteCommentHandler = (index) => {
this.props.onDeletePost(index);
}
ShowFunction = () => {
this.setState({showNewPost: !this.state.showNewPost})
}
render() {
let cardData = <center> <Spinner/></center>
if(!this.props.loading){
cardData = <div className="posts">
{/*add font awesome search icon*/}
<div className="topSection">
<input type="text" className="Searchbar" placeholder="Search for people, topics or keywords..."/>
<Button className="btn btn-primary">Search</Button>
<NewPost/>
</div>
{this.props.data.reverse().map((res) => (
<div>
<Card
key={res.id}
className="Cards"
>
<Card.Body
className="container">
<h6>
@ANONYMOUS
</h6>
<Card.Text>
{res.Comment}
</Card.Text>
<div>
<center>
<img src={res.ImageUrl} width = "680px" height="390px" />
</center>
</div>
<br/>
<Button className="btn btn-danger"
style={{float:"right", width:"35px", height:"35px", borderRadius:"5px"}}
onClick={() => this.DeleteCommentHandler(res.id)}>
<center>
<FontAwesomeIcon icon={faTrash} style={{width:"11px"}}/>
</center>
</Button>
</Card.Body>
<Card.Footer style={{position:"relative", marginTop:"20px"}}>
{res.Date}
</Card.Footer>
</Card>
</div>
)
)}
</div>
}
return(
<div>
{cardData}
</div>
);
}
}
const mapStateToProps = state => {
return {
data: state.Data,
loading: state.loading
};
};
const mapDispatchToProps = dispatch => {
return {
onFetchPosts: () => dispatch(actions.FetchPost()),
onDeletePost: (postId) => dispatch(actions.DeletePost(postId))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(PostComment);
这是 action.js 文件
import axios from '../../axios-comments';
import * as actionTypes from './actionTypes';
export const NewPostSuccess = (id, postData) => {
return {
type: actionTypes.New_Post_Success,
payload: {
data: postData,
id: id
}
}
}
export const NewPostError = (error) => {
return {
type: actionTypes.New_Post_Error,
error: error
}
}
export const NewPost = (postData) => {
return (dispatch) => {
axios.post('/Data.json', postData)
.then(response => {
console.log(response.data);
dispatch(NewPostSuccess(response.data.name, postData));
})
.catch(error => {
dispatch(NewPostError(error));
})
}
}
export const DeletePostSuccess = (id) => {
return {
type: actionTypes.Delete_Post_Success,
index: id
}
}
export const DeletePost = (index) => {
return (dispatch) => {
axios.delete('/Data/'+ index + '.json')
.then(response => {
console.log(response.data);
dispatch(DeletePostSuccess(index))
})
}
}
export const FetchPostStart = () => {
return {
type: actionTypes.Fetch_Post_Start
};
};
export const FetchPostSuccess = (fetchedData) => {
return {
type: actionTypes.Fetch_Post_Success,
payload: fetchedData
}
}
export const FetchPostError = (error) => {
return {
type: actionTypes.Fetch_Post_Error,
error: error
}
}
export const FetchPost = () => {
return dispatch => {
dispatch(FetchPostStart());
axios.get('/Data.json')
.then(response => {
const fetchedData = [];
for(let key in response.data){
fetchedData.push({
...response.data[key],
id: key
});
}
dispatch(FetchPostSuccess(fetchedData));
})
.catch(error => {
dispatch(FetchPostError(error));
});
}
}
这是reducer函数
import * as actionTypes from '../actions/actionTypes';
const initialState = {
Data: [],
loading: false
}
const reducer = (state = initialState, action) => {
switch(action.type){
case actionTypes.New_Post_Error:
return {
...state,
loading:false
}
case actionTypes.New_Post_Success:
return {
...state,
loading: false,
Data: [...state.Data, action.payload.data]
}
case actionTypes.Delete_Post_Success:
const selectedComment = state.Data.filter(res => res.id !== action.index);
return {
...state,
loading: false,
Data: selectedComment
}
case actionTypes.Fetch_Post_Start:
return {
...state,
loading:true
}
case actionTypes.Fetch_Post_Error:
return {
...state,
loading:false
}
case actionTypes.Fetch_Post_Success:
return {
...state,
loading: false,
Data: action.payload
}
default: return state;
}
}
export default reducer;
非常感谢
据我所知,是的,您填充了 state.Data
,但请注意在旧对象中您的 属性 键是 PascalCased 而不是像新添加的 post 对象那样的驼峰式.
在您的代码中,您正在映射 res.Comment
和 res.ImageUrl
!
虽然我强烈建议您采用更标准的 pascalCased 命名约定(可能从您的 JSON 数据中的源开始!!),但您可以更新新的 post 成功减速器案例以保持状态不变。
case actionTypes.New_Post_Success:
const { comment: Comment, imageUrl: ImageUrl } = action.payload.data;
return {
...state,
loading: false,
Data: [
...state.Data,
{ Comment, ImageUrl },
],
}