在事件处理程序中和ComponentDidUpdate中调度相同的动作?

时间:2019-12-17 01:24:48

标签: reactjs redux react-redux

最近,我正在学习Redux + Redux thunk来处理异步操作。在official tutorial about the Reddit API中,我不太明白为什么我们需要多次分派fetchPostsIfNeeded(如果需要,可以分派帖子)。链接为Official,而在线编辑者的{ {3}}。

在StackOverflow的另一个Here中,他们对此进行了讨论,但他们只选择使用event handlercomponentDidUpdate,而不是同时使用两者。

问题是:在官方示例中,在componentDidUpdate中处理冗余是否为( )是否已经存在handleChangehandleRefreshClick(如果有更新,则可以获取帖子的 )?我在此处附加了React life cycle,以便更好地理解。

post

文件AsyncApp.js

代码段

class AsyncApp extends Component {
  constructor(props) {
    super(props)
    this.handleChange = this.handleChange.bind(this)
    this.handleRefreshClick = this.handleRefreshClick.bind(this)
  }

  componentDidMount() {
    const { dispatch, selectedSubreddit } = this.props
    dispatch(fetchPostsIfNeeded(selectedSubreddit))
  }

  componentDidUpdate(prevProps) {
  ^^^^^^^^^^^^^^^^^^
    if (this.props.selectedSubreddit !== prevProps.selectedSubreddit) {
      const { dispatch, selectedSubreddit } = this.props
      dispatch(fetchPostsIfNeeded(selectedSubreddit))
               ^^^^^^^^^^^^^^^^^^

    }
  }

  handleChange(nextSubreddit) {
  ^^^^^^^^^^^^
    this.props.dispatch(selectSubreddit(nextSubreddit))
    this.props.dispatch(fetchPostsIfNeeded(nextSubreddit))
                        ^^^^^^^^^^^^^^^^^^
  }

  handleRefreshClick(e) {
  ^^^^^^^^^^^^^^^^^^^^
    e.preventDefault()

    const { dispatch, selectedSubreddit } = this.props
    dispatch(invalidateSubreddit(selectedSubreddit))
    dispatch(fetchPostsIfNeeded(selectedSubreddit))
             ^^^^^^^^^^^^^^^^^^
  }

  render() {
    const { selectedSubreddit, posts, isFetching, lastUpdated } = this.props
    return (
      <div>
        <Picker
          value={selectedSubreddit}
          onChange={this.handleChange}
          options={['reactjs', 'frontend']}
        />
        <p>
          {lastUpdated && (
            <span>
              Last updated at {new Date(lastUpdated).toLocaleTimeString()}.{' '}
            </span>
          )}
          {!isFetching && (
            <button onClick={this.handleRefreshClick}>Refresh</button>
          )}
        </p>
        {isFetching && posts.length === 0 && <h2>Loading...</h2>}
        {!isFetching && posts.length === 0 && <h2>Empty.</h2>}
        {posts.length > 0 && (
          <div style={{ opacity: isFetching ? 0.5 : 1 }}>
            <Posts posts={posts} />
          </div>
        )}
      </div>
    )
  }
}

function mapStateToProps(state) {
  const { selectedSubreddit, postsBySubreddit } = state
  const { isFetching, lastUpdated, items: posts } = postsBySubreddit[
    selectedSubreddit
  ] || {
    isFetching: true,
    items: []
  }

  return {
    selectedSubreddit,
    posts,
    isFetching,
    lastUpdated
  }
}

export default connect(mapStateToProps)(AsyncApp)

谢谢

1 个答案:

答案 0 :(得分:1)

在这个确切的示例中,componentDidUpdate没有用,因为更新请求是从事件处理程序内部发出的。但是,如果您还有其他组件,例如说ThirdPartyUpdater,它将在SPA中另一个位置的某个地方显示Picker,则componentDidUpdate会起到重新获取帖子的作用。

我已经修改provided demo来展示这一点。上层选取器是与AsyncApp分开的组件,它只是更新selectedSubredditAsyncApp然后接收更新的道具并在componentDidUpdate中请求新的subreddit。

从我的角度来看,最好将fetchPostsIfNeeded放在selectSubreddit动作创建者中。每当我们选择新的subreddit时,都应立即重新获取帖子。因此,将这两个步骤分开可能会在将来产生错误。