使用redux工具包状态管理,根据从SubmitForm组件获取的值更新组件UI

eblbsuwk  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(175)

我的store.js文件

import commentsReducer from "./stateSlices/commentsSlice";
export default configureStore({
    reducer: {
        dishes: dishesReducer,
        comments: commentsReducer,
        leaders: leadersReducer,
        promotions: promotionsReducer,
    },
});

我的注解Slice.js文件

import { COMMENTS } from "../../shared/comments";
import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    comments: COMMENTS,
};
export const stateSlice = createSlice({
    name: "comments",
    initialState,
// Updated the reducer file as below
reducers: {
        addComment: {
            reducer: (state = initialState.comments, action) => {
                state.comments = state.comments.concat(action.payload);
            },
            prepare: (value) => {
                return {
                    payload: {
                        ...value,
                        date: new Date().toISOString(),
                        id: Math.random(),
                    },
                };
            },
        },
    },

});

export default stateSlice.reducer;

我的dishdetail.js文件

const Dishdetail = (props) => {
    if (props.dish != null) {
        return (
            <div className="container ">
                <div className="row ">
                    <div className="col-12 col-sm-5 col-md-5 m-1">
                        <RenderComments comments={props.comments} />
                    </div>
                </div>
            </div>
        );
    } else {
        return <div></div>;
    }
};

export default Dishdetail;

RenderComments组件实现

function RenderComments({ comments, commentsName }) {
// created dishId constant to get the dishId of selected dish and 
//need only first index dishId and passed it as prop to 
//SubmitComment component as file like this
//changed below line
const dishId = comments.map((x) => x.dishId)[0];
    if (comments != null) {
        return (
            <>
                <div>
                    {comments.map((comment) => {
                        const options = { year: "numeric", month: "short", day: "2-digit" };
                        return (
                            <div key={comment.id}>
                                <ul className="list-unstyled">
                                    <li>{comment.comment}</li>
                                    <li>
                                        --{comment.author} {new Date(comment.date).toLocaleDateString("en-us", options)}
                                    </li>
                                </ul>
                            </div>
                        );
                    })}
                    <SubmitComment dishId={dishId} />
                </div>
            </>
        );
    } else {
        return <div></div>;
    }
}

和我的SubmitComment.js组件

function SubmitComment() {
    const [modal, setModal] = useState(false);

    const toggle = () => setModal(!modal);
    const {
        register,
        formState: { errors },
        handleSubmit,
        reset,
    } = useForm();

    const onSubmit = (data) => {
        console.log(data);
// to get the data from input fields
const { rating, author, comment } = data;
//dispatched the addComment action, here dishId is from props 
        dispatch(addComment({ dishId, rating, author, comment }));

// Finally subscribed to the store by useSelector method in main
// component which is parent component of renderComments component 
//which in turn is parent component of SubmitComments component

        reset();
    };

    return (
        <>
            <div>
                <Button color="primary" onClick={toggle}>
                    Submit
                </Button>
                <Modal isOpen={modal} toggle={toggle} fade={false}>
                    <ModalHeader toggle={toggle}>Submit Comment</ModalHeader>
                    <ModalBody>
                        <form onSubmit={handleSubmit(onSubmit)}>
                            <div className="mb-3">
                                <label htmlFor="rating" className="form-label">
                                    Rating
                                </label>
                                <select
                                    name="rating"
                                    className="form-select "
                                    aria-label="Default select example"
                                    {...register("rating")}
                                >
                                    <option value="1">1</option>
                                    <option value="2">2</option>
                                    <option value="3">3</option>
                                    <option value="4">4</option>
                                    <option value="5">5</option>
                                </select>
                            </div>
                            <div className="mb-3">
                                <label htmlFor="name" className="form-label">
                                    Your Name
                                </label>
                                <input
                                    type="text"
                                    className="form-control"
                                    id="name"
                                    placeholder="Your Name"
                                    name="name"
                                    {...register("name", { required: true, maxLength: "15" })}
                                />
                                <small className="form-text text-danger">
                                    {errors.name?.type === "required" && "This field is required"}
                                    {errors.name?.type === "maxLength" && "Maximum 15 characters are allowed"}
                                </small>
                            </div>
                            <div className="mb-3">
                                <label htmlFor="comment" className="form-label">
                                    Comment
                                </label>
                                <textarea
                                    type="text"
                                    name="comment"
                                    className="form-control"
                                    id="comment"
                                    aria-describedby="comment"
                                    rows="6"
                                    {...register("comment")}
                                />
                            </div>

                            <button type="submit" className="btn btn-primary">
                                Submit
                            </button>
                        </form>
                    </ModalBody>
                </Modal>
            </div>
        </>
    );
}

export default SubmitComment;

我希望,一旦我单击submitcomment表单,我在字段(即评级、作者和评论)中输入的所有值都应该添加到renderComment组件中。

像这个

,我已经尝试在表单中单击提交后添加调度操作,并尝试使用useSelector在rendercomments组件文件中使用它,但我无法执行此操作
因此,如果有人能从这里描述redux流和基本工作流,我就可以实现此功能

yfwxisqw

yfwxisqw1#

1在commentSlice.js文件中创建了reducer
2在Dishdetail组件中进行了以下更改:在renderComments函数中,创建了dishId常量以获取所选菜肴的dishId,只需首先索引dishId,并将其作为属性传递给SubmitComment组件(renderComments的子组件)
3在SubmitComment中接收到作为prop的dishId,并使用dispatch将其作为有效负载与从用户输入字段接收到的其他值沿着传递给操作addComment
4最后使用useSelectore订阅Main组件中的新状态,并将其作为prop传递给Dishdetail组件(Main组件的子组件)
已成功实现所需功能。
我已根据更改更新了问题。

相关问题