在redux中为简单的CRUD应用程序构建reducer

时间:2016-10-06 13:37:43

标签: redux

因此,我正在使用React + Redux创建一个非常简单的CRUD风格应用程序。有一个(让我们称之为)帖子的集合,有一个API,我希望能够列出这些帖子,然后当用户点击一个时,进入关于该帖子的详细信息页面。

所以我有一个帖子减速器。最初我开始使用从redux实际示例中获取的方法。这通过索引缩减器维护对象的缓存,当你执行“获取帖子”时,它会检查缓存,如果它在那里,它会返回该缓存,否则它会进行适当的API调用。当组件挂载时,它们会尝试从缓存中获取内容,如果它们不存在,则等待(返回false)直到它们为止。

虽然这样可行,但出于各种原因我现在需要进行非缓存,即每次加载/ posts /:postId页面时我都需要通过API获取帖子。

我意识到在非redux世界中你只需要在componentDidMount中执行fetch(),然后在那里执行setState()。但是我希望将存储在reducer中的帖子作为应用程序的其他部分可以调用修改这些帖子的操作(比如说一个websocket或者只是一个复杂的redux连接组件)。

我见过人们使用的一种方法是在reducer中使用“active”项,如下例所示:https://github.com/rajaraodv/react-redux-blog/blob/master/public/src/reducers/reducer_posts.js

虽然这没关系,但是必须加载活动帖子的每个组件都必须有一个componentWillUnmount操作才能重置活动帖子(请参阅resetMe:https://github.com/rajaraodv/react-redux-blog/blob/master/public/src/containers/PostDetailsContainer.js)。如果它没有重置活动帖子,它将在显示下一个帖子时闲置(它可能会在API调用完成时闪烁一小段时间,但它仍然不好)。通常强制每个想要查看帖子的页面在componentWillUnmount中执行resetMe()都会像恶臭一样崩溃。

那么有没有人有任何想法或看到一个很好的例子?这似乎是一个简单的案例,我有点惊讶我找不到任何材料。

2 个答案:

答案 0 :(得分:0)

如何做到这一点取决于您现有的减速机,但我只是换一个新的减速机

<强> reducers/post.js

import { GET_ALL_POSTS } from './../actions/posts';

export default (state = {
  posts: []
}, action) => {
  switch (action.type) {
    case GET_ALL_POSTS:
      return Object.assign({}, state, { posts: action.posts });
    default:
      return state;
  }
};

这很容易理解,只需触发一个动作来获取所有帖子,并用减速器中的新帖子替换以前的帖子。

使用componentDidMount触发GET_ALL_POSTS操作,并在状态中使用布尔标记来了解帖子是否已加载,因此您不必每次都重新加载它们,仅在组件安装时。

<强> components/posts.jsx

import React from 'react';

export default class Posts extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      firstLoad: false
    };
  }

  componendDidMount() {
    if (!this.state.firstLoad) {
        this.props.onGetAll();
        this.setState({
            firstLoad: true
        });
    }
  }

  // See how easy it is to refresh the lists of posts
  refresh() {
    this.props.onGetAll();
  }

  render () {
    ...

    // Render your posts here
    { this.props.posts.map( ... ) }
    ...
  }
}

我们只是错过了将帖子和事件传递给组件的容器

<强> containers/posts.js

import { connect } from 'react-redux';
import { getPosts } from './../actions/posts';
import Posts from './../components/posts.jsx';

export default connect(
  state => ({ posts: state.posts }),
  dispatch => ({ onGetAll: () => dispatch(getPosts()) })
);

这是一个非常简单的模式,我已在许多应用程序中使用它

答案 1 :(得分:0)

如果你使用react-router,你可以利用onEnter钩子。