我正在调度一个操作,该操作应该从用户那里获取输入并将其存储在数据库中,但是,当我在调度该操作后检查redux中的posts状态时,有一个空值附加到实际post之前的state数组。这阻止了我处理post数组中的实际数据。基本上我'我想知道如何防止空值被追加每次我派遣一个新的职位。这里是相关的代码
snippet和图像。
后复位器:
import { enableAllPlugins, produce } from 'immer';
enableAllPlugins();
const initialState = {
posts: [],
loading: false,
error: false,
uploading: false,
};
const postReducer = produce((draftstate, action = {}) => {
switch (action.type) {
case 'UPLOAD_START':
draftstate.loading = true;
draftstate.error = false;
case 'UPLOAD_SUCCESS':
draftstate.posts.push(action.data);
draftstate.uploading = false;
draftstate.error = false;
case 'UPLOAD_FAIL':
draftstate.uploading = false;
draftstate.error = true;
default:
return draftstate;
}
}, initialState);
export default postReducer;
上载发布操作:
export const uploadPost = (data) => async (dispatch) => {
dispatch({ type: 'UPLOAD_START' });
try {
const newPost = await UploadApi.uploadPost(data);
console.log('new post before', newPost);
dispatch({ type: 'UPLOAD_SUCCESS', data: newPost.data });
} catch (error) {
console.log(error);
dispatch({ type: 'UPLOAD_FAIL' });
}
};
邮政编码:
import React, { useState, useRef } from "react";
import ProfileImage from "../../img/profileImg.jpg";
import "./PostShare.css";
import { UilScenery } from "@iconscout/react-unicons";
import { UilPlayCircle } from "@iconscout/react-unicons";
import { UilLocationPoint } from "@iconscout/react-unicons";
import { UilSchedule } from "@iconscout/react-unicons";
import { UilTimes } from "@iconscout/react-unicons";
import { useSelector, useDispatch } from "react-redux";
import { uploadImage, uploadPost } from "../../actions/uploadAction";
const PostShare = () => {
const loading = useSelector((state) => state.postReducer.uploading);
const [image, setImage] = useState(null);
const imageRef = useRef();
const desc = useRef();
const dispatch = useDispatch();
const { user } = useSelector((state) => state.authReducer.authData);
// handle Image Change
const onImageChange = (event) => {
if (event.target.files && event.target.files[0]) {
let img = event.target.files[0];
setImage(img);
}
};
const reset = () => {
setImage(null);
desc.current.value = "";
};
const handleSubmit = async (e) => {
e.preventDefault();
const newPost = {
userId: user._id,
desc: desc.current.value,
};
if (image) {
const data = new FormData();
const filename = Date.now() + image.name;
data.append("name", filename);
data.append("file", image);
newPost.image = filename;
console.log(newPost);
try {
dispatch(uploadImage(data));
} catch (error) {
console.log(error);
}
}
dispatch(uploadPost(newPost));
reset();
};
return (
<div>
<div className="PostShare">
<img src={ProfileImage} alt="" />
<div>
<input
ref={desc}
required
type="text"
placeholder="What's happening"
/>
<div className="postOptions">
<div
className="option"
style={{ color: "var(--photo)" }}
onClick={() => imageRef.current.click()}
>
<UilScenery />
Photo
</div>
<div className="option" style={{ color: "var(--video" }}>
<UilPlayCircle />
Video
</div>
<div className="option" style={{ color: "var(--location)" }}>
<UilLocationPoint />
Location
</div>
<div className="option" style={{ color: "var(--shedule)" }}>
<UilSchedule />
Schedule
</div>
<button
className="button ps-button"
onClick={handleSubmit}
disabled={loading}
>
{loading ? "Uploading..." : "Share"}
</button>
<div style={{ display: "none" }}>
<input
type="file"
name="myImage"
ref={imageRef}
onChange={onImageChange}
/>
</div>
</div>
{image && (
<div className="previewImage">
<UilTimes onClick={() => setImage(null)} />
<img src={URL.createObjectURL(image)} alt="" />
</div>
)}
</div>
</div>
</div>
);
};
export default PostShare;
如果有帮助的话,我很乐意提供任何其他细节。
更新代码的其他部分:
RETRIEVING_SUCCESS调度程序:
import * as PostApi from '../api/PostRequest';
export const getTimelinePosts = (id) => async (dispatch) => {
dispatch({ type: 'RETRIEVING_START' });
try {
const { data } = await PostApi.getTimelinePosts(id);
dispatch({ type: 'RETRIEVING_SUCCESS', data: data });
} catch (error) {
dispatch({ type: 'RETRIEVING_FAIL' });
console.log(error);
}
};
getTimelinePosts用法:
import React, { useEffect } from 'react';
import './Posts.css';
import { PostsData } from '../../Data/PostsData';
import { useDispatch, useSelector } from 'react-redux';
import { getTimelinePosts } from '../../actions/postAction';
import Post from '../Post/Post';
const Posts = () => {
const dispatch = useDispatch();
const { user } = useSelector((state) => state.authReducer.authData);
let { posts, loading } = useSelector((state) => state.postReducer);
console.log('posts content', posts);
useEffect(() => {
dispatch(getTimelinePosts(user._id));
}, []);
return (
<div className="Posts">
{/* {posts.map((post, id) => {
return <Post data={post} id={id}></Post>;
})} */}
</div>
);
};
export default Posts;
2条答案
按热度按时间5gfr0r5j1#
在postReducer中,让我们删除switch语句上的默认值,我们不需要reducer上的默认值,因为其他操作将在此处执行,并且代码使所有状态返回初始状态。
mmvthczy2#
好的,我找到了一个解决posts数组中null项的方法。虽然我不知道为什么会这样,但它只会将实际的posts附加到posts数组中,而不会输入null。我所要做的就是改变reducer更新状态的方式。我最初使用immer,但现在不再使用了。下面是代码: