首页 > 解决方案 > 保存时 React Redux 中的引用项状态未更新

问题描述

我的博客模型引用了我在猫鼬中的用户模型(反之亦然)。在我的博客应用程序中,当我为用户创建博客文章时,博客状态会更新,但是当我在 redux 商店中检查用户的状态时,用户的关联博客不会更新。如果我刷新显示用户的页面,它最终会刷新以显示更新的博客文章,但不确定为什么状态没有立即更新。

因此,这是我创建新博客文章的起始代码:

import React from "react";
import { connect } from "react-redux";
import { createBlog } from "../reducers/blogReducer";
import { withRouter } from "react-router-dom";
import { setNotification } from "../reducers/notificationReducer";
import { useField } from "../hooks";
import { Form } from "semantic-ui-react";

const NewBlog = props => {
  const newTitle = useField("text");
  const newAuthor = useField("text");
  const newURL = useField("text");

  const addBlog = event => {
    event.preventDefault();

    const blogObject = {
      url: newURL.value,
      title: newTitle.value,
      author: newAuthor.value
    };
    props.createBlog(blogObject);
    props.history.push("/blogs");
    setNotification(`New Blog Created!`, 4);
    newTitle.reset();
    newAuthor.reset();
    newURL.reset();
  };

  return (
    <Form onSubmit={addBlog}>
      <Form.Field>
        <Form.Input {...newTitle} reset={null} label="Title" id="title" />
      </Form.Field>
      <Form.Field>
        <Form.Input {...newAuthor} reset={null} label="Author" id="author" />
      </Form.Field>
      <Form.Field>
        <Form.Input {...newURL} reset={null} label="URL" id="url" />
      </Form.Field>
      <Form.Button type="submit">add blog</Form.Button>
    </Form>
  );
};

const mapDispatchToProps = {
  createBlog,
  setNotification
};

const AddBlog = withRouter(NewBlog);

export default connect(null, mapDispatchToProps)(AddBlog);

这是我的 createBlog 动作创建者(和减速器)

export const createBlog = content => {
  return async dispatch => {
    const newBlog = await blogService.create(content);
    dispatch({
      type: "NEW_BLOG",
      data: newBlog
    });
  };
};

  case "NEW_BLOG":
      return [...state, action.data];

和 axios 创建调用

const create = async newObject => {
  const config = {
    headers: { Authorization: token }
  };
  const response = await axios

.post(baseUrl, newObject, config);
      return response.data;
    };

然后是我调用帖子的后端:

blogsRouter.post("/", async (request, response, next) => {
  const data = request.body;

  const token = getTokenFrom(request);

  try {
    const decodedToken = jwt.verify(token, process.env.SECRET);
    if (!token || !decodedToken.id) {
      return response.status(401).json({ error: "token missing or invalid" });
    }

    const user = await User.findById(decodedToken.id);

    const blog = new Blog({
      title: data.title,
      author: data.author,
      likes: isNaN(data.likes) ? 0 : data.likes,
      url: data.url,
      user: user._id
    });

    const savedBlog = await blog.save();
    user.blogs = user.blogs.concat(savedBlog._id);
    await user.save();
    response.status(201).json(savedBlog.toJSON());
  } catch (error) {
    next(error);
  }
});

我在 App.js 中的完整路由器容器

<Container>
      <Router>
        <Notification />
        <div>
          <Navbar />
          <Switch>
            <Route path="/login">
              <Login />
            </Route>
            {props.loggedUser && (
              <React.Fragment>
                <Route exact path="/">
                  <Blogs />
                </Route>
                <Route exact path="/blogs">
                  <Blogs />
                </Route>
                <Route exact path="/newblog">
                  <AddBlog />
                </Route>
                <Route
                  exact
                  path="/blogs/:id"
                  render={({ match }) => (
                    <Blog
                      blog={blogById(match.params.id)}
                      user={props.loggedUser}
                      history={props.history}
                    />
                  )}
                />
                <Route exact path="/users">
                  <Users />
                </Route>
                <Route
                  exact
                  path="/users/:id"
                  render={({ match }) => (
                    <User user={userById(match.params.id)} />
                  )}
                />
              </React.Fragment>
            )}
            <Route exact path="/newuser">
              <CreateUser />
            </Route>
            <Redirect to="/login">
              <Login />
            </Redirect>
            )}
          </Switch>
        </div>
      </Router>
      <div>
        <br />
        <em>Blog app, John 2019</em>
      </div>
    </Container>

标签: reactjsmongodbreduxreact-redux

解决方案


您将在与启动将博客保存到数据库的函数调用相同的事件循环中重定向到博客页面。您需要先等待博客文章保存,然后才能重定向:

  const addBlog = async event => { // <-- make it async
    event.preventDefault();

    const blogObject = {
      url: newURL.value,
      title: newTitle.value,
      author: newAuthor.value
    };
    await props.createBlog(blogObject); // <-- wait for it to finish
    props.history.push("/blogs");
    setNotification(`New Blog Created!`, 4);
    newTitle.reset();
    newAuthor.reset();
    newURL.reset();
  };

推荐阅读