【问题标题】:React - Redux; .map function duplicates Array sometimes反应 - Redux; .map 函数有时会重复数组
【发布时间】:2019-11-26 13:40:20
【问题描述】:

我在一个组件中有一个 .map 函数:

let recentItemsMarkup = loading ? (
      <p>Items are loading...</p>
    ) : (
      items.map(item => (
        <ShoppingItem
          key={item._id}
          id={item._id}
          name={item.name}
          createdAt={item.date}
        />
      ))
    );

当我发布一个项目时,有时(并非总是)它会在视图中重复,但不会在数据库中重复。 DB 工作正常,但不知何故,在我发布项目后,它并不总是正确设置项目, 这是动作和减速器:

  //post item
  export const postItem = newItem => dispatch => {
  dispatch({ type: LOADING_UI });
  axios
    .post("http://localhost:5000/api/items", newItem)
    .then(res => {
      dispatch({
        type: POST_ITEM,
        payload: res.data
      });
    })
    .catch(err => {
      dispatch({
        type: SET_ERRORS,
        payload: err.response.data
      });
    });
};

和减速器:

const initialState = {
  items: [],
  item: {},
  loading: false
};

export default (state = initialState, action) => {
  switch (action.type) {
    case LOADING_ITEMS:
      return {
        ...state,
        loading: true
      };
    case GET_ITEMS:
      return {
        ...state,
        items: action.payload,
        loading: false
      };
    case POST_ITEM:
      return {
        ...state,
        items: [action.payload, ...state.items]
      };

    case DELETE_ITEM:
      return {
        ...state,
        items: state.items.filter(item => item._id !== action.payload)
      };
    default:
      return state;
  }
};

我检查了 ID 和数据库,一切正常,ID 是唯一的,为什么会这样?

screenshot

还有购物项目组件:

class ShoppingItem extends Component {


  render() {
    const { authenticated } = this.props.user;
    const { name, createdAt, classes, id } = this.props;
    const deleteButton = authenticated ? (
      <DeleteItem id={id} />
    ) : null;
    return (
      <Card className={classes.card}>
        <CardContent>
          <Typography variant="body1" color="textPrimary">
            {this.props.id}
          </Typography>
          <Typography variant="body1" color="textPrimary">
            {name}
          </Typography>
          {deleteButton}
          <Typography color="textSecondary">
            {dayjs(createdAt).format("h:mm a, MMM DD YYYY")}
          </Typography>
        </CardContent>
      </Card>
    );
  }
}

ShoppingItem.propTypes = {
  name: PropTypes.string.isRequired,
};

const mapStateToProps = state => ({
  user: state.user
});

const actionsToProps = {
  deleteItem
};

export default connect(
  mapStateToProps,
  actionsToProps
)(withStyles(styles)(ShoppingItem));

【问题讨论】:

  • 尝试在每次发布项目时发送GET_ITEMS 并展示发生了什么!
  • 代码中已经这样做了:handleSubmit = event =&gt; { event.preventDefault(); const newItem = { name: this.state.name, handler: this.props.user.user.name }; this.props.postItem(newItem); this.props.getItems(); };

标签: javascript arrays reactjs ecmascript-6 redux


【解决方案1】:

您的后端似乎返回了一组项目以及新项目,因此在这种情况下,您只需将它们设置为状态,而不是添加到现有项目:

case POST_ITEM:
      return {
        ...state,
        items: action.payload
      };

【讨论】:

  • 我尝试了很多版本,包括你,但仍然偶尔会出错。我没有得到它的逻辑,它只是有时起作用。因为如果 id 是唯一的,那么 db 就可以了,它有时只是在视图上重复吗?它似乎以某种方式同时推送新项目和所有项目(包括新项目)
【解决方案2】:

因为

案例 POST_ITEM: 返回 { ...状态, 项目:[action.payload, ...state.items] };

只需发送需要添加的项目,然后在后端处理插入。

【讨论】:

    【解决方案3】:

    好的,我解决了这个问题, 我的失败是,我在“postItem”函数中添加了“getItems”,这会导致重复,因为当我发布一个项目时,它已经刷新了页面并从 componentDidMount 方法加载了项目。所以好像我不是很理解这个逻辑,就是当 state 或 props 发生变化时,页面会自动刷新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-02
      • 2021-06-14
      • 2019-03-04
      • 1970-01-01
      • 2021-09-16
      • 2023-03-17
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多