为redux中的简单积垢应用构建减速机

为redux中的简单积垢应用构建减速机,redux,Redux,所以我正在创建一个非常简单的CRUD风格的应用程序,使用React+Redux。有一个(让我们调用它们)帖子的集合,带有API,我希望能够列出这些帖子,然后当用户单击其中一个帖子时,进入关于该帖子的详细页面 所以我有一个减速机。最初,我开始使用redux现实世界示例中的方法。这将通过索引缩减器维护对象的缓存,当您执行“get post”时,它将检查缓存,如果缓存在那里,它将返回该缓存,否则将进行相应的API调用。当组件挂载时,它们尝试从缓存中获取内容,如果它们不在缓存中,则等待(返回false)

所以我正在创建一个非常简单的CRUD风格的应用程序,使用React+Redux。有一个(让我们调用它们)帖子的集合,带有API,我希望能够列出这些帖子,然后当用户单击其中一个帖子时,进入关于该帖子的详细页面

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

虽然这工作正常,但由于各种原因,我现在需要使用非缓存,即每次加载/posts/:postd页面时,我都需要通过API获取帖子

我意识到在非redux世界中,您只需在componentDidMount中执行fetch(),然后在此基础上设置state()。但我希望帖子存储在reducer中,因为应用程序的其他部分可能会调用修改这些帖子的操作(例如websocket或只是一个复杂的redux连接组件)

我看到人们使用的一种方法是在减速机中使用“活动”项,如以下示例:

虽然这是正常的,但加载活动post的每个组件都必须有一个componentWillUnmount操作来重置活动post(请参阅resetMe:)。如果它没有重置活动post,它将在显示下一个post时挂起(在进行API调用时,它可能会闪烁一小段时间,但仍然不好)。通常,强制每个想查看帖子的页面在组件中执行resetMe()操作会让卸载感觉很糟糕


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

如何做取决于您已经存在的减速器,但我将制作一个新的减速器

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;
  }
};
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( ... ) }
    ...
  }
}
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()) })
);
这很容易理解,只需启动一个操作即可获取所有帖子,并用减速机中的新帖子替换以前的帖子

使用
componentDidMount
启动
GET_ALL_POSTS
操作,并在状态中使用一个布尔标志来知道是否加载了POSTS,因此您不会每次都重新加载它们,只在组件装载时才加载

组件/posts.jsx

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;
  }
};
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( ... ) }
    ...
  }
}
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()) })
);
我们只是缺少将POST和事件传递给组件的容器

containers/posts.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;
  }
};
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( ... ) }
    ...
  }
}
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()) })
);

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

如何使用它取决于您已经存在的减速机,但我将制作一个新的减速机

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;
  }
};
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( ... ) }
    ...
  }
}
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()) })
);
这很容易理解,只需启动一个操作即可获取所有帖子,并用减速机中的新帖子替换以前的帖子

使用
componentDidMount
启动
GET_ALL_POSTS
操作,并在状态中使用一个布尔标志来知道是否加载了POSTS,因此您不会每次都重新加载它们,只在组件装载时才加载

组件/posts.jsx

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;
  }
};
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( ... ) }
    ...
  }
}
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()) })
);
我们只是缺少将POST和事件传递给组件的容器

containers/posts.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;
  }
};
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( ... ) }
    ...
  }
}
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()) })
);

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

如果你使用react路由器,你可以利用OneNet hook。

如果你使用react路由器,你可以利用OneNet hook。

你说的“如果没有重置活动post”是什么意思?你能提供一个真实的用例吗?你所说的“如果它没有重置激活的帖子”是什么意思?你能提供一个真实的用例吗?