如何在react redux中防止重复的列表对象

use*_*410 5 reactjs redux redux-thunk

我的组件存在重复问题,我从 api 获取了一些虚拟数据。

以下哪种方法一切正常,但是当我更改路线并转到另一个页面并返回到我列出用户对象的页面时。每次都有我的对象的重复列表。我该如何预防?

这是我的组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux' 
import {getAllUsers} from '../actions/user'

class users extends Component {
  componentDidMount() {
    this.props.getAllUsers()
  }

  render() {
    let usersList = this.props.users.map(user => <li key={user.id}>{user.name}</li>)

    return (
      <div>
        <h1>user list</h1>
        <ul>
          {usersList}
        </ul>
      </div>
    )
  }
}

const mapStateToProps = state => ({
  users: state.users
})


function mapDispatchToProps(dispatch) {
  return {
    getAllUsers: bindActionCreators(getAllUsers, dispatch)
  }
} 

export default connect(mapStateToProps, mapDispatchToProps)(users)
Run Code Online (Sandbox Code Playgroud)

这是我的减速器:

import { FETCH_USERS } from '../actions/user'

let initialState = []

export default (state = initialState, action) => {
    switch (action.type) {
        case FETCH_USERS:
            return [...state, ...action.payload]
        default:
            return state
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的行动:

export const FETCH_USERS = 'FETCH_USERS';

export const getAllUsers = () => {
    return(dispatch) => {
        fetch('https://jsonplaceholder.typicode.com/users')
        .then(res => res.json())
        .then(users => {
            dispatch({
                type: FETCH_USERS,
                payload: users
            })
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

tom*_*der 6

目前有几个选项可供您使用:

  1. 评估您是否需要执行 API 请求。如果您已经发出请求,是否可以仅依赖 Redux 存储中先前缓存的数据,还是必须依赖每次组件安装时获取的新用户?
componentDidMount() {
    if (!this.props.users.length) {
        this.props.getAllUsers();
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果每次组件挂载时都需要获取新数据,为什么不直接在组件卸载时清除 Redux 存储中的数据呢?例如

成分:

componentWillUnmount() {
    this.props.clearUsers();
}
Run Code Online (Sandbox Code Playgroud)

减速器:

import { FETCH_USERS, CLEAR_USERS } from '../actions/user'

let initialState = []

export default (state = initialState, action) => {
    switch (action.type) {
        case FETCH_USERS:
            return [...state, ...action.payload]
        case CLEAR_USERS:
            return initialState
        default:
            return state
    }
}
Run Code Online (Sandbox Code Playgroud)

还有其他一些选项可供调查,但这应该有望解决您的问题:)

编辑:

正如评论中指出的那样,作者的减速器有点到处都是。我希望将减速器重构为以下内容:

import { FETCH_USERS } from '../actions/user'

const initialState = {
    users: [],
}

export default (state = initialState, action) => {
    switch (action.type) {
        case FETCH_USERS:
            return {
                ...state,
                users: [...action.payload],
            }
        default:
            return state
    }
}
Run Code Online (Sandbox Code Playgroud)

这将解决每次安装组件时重复用户的问题,同时确保减速器可以在未来扩展,而不会冒整个状态被替换的风险。