React Redux返回道具列表[Metronic主题]

问题描述 投票:0回答:1

我有一个关于React-Redux在初始化页面时返回特定于Redux的道具列表的问题。如果我console.log this.props.address(我要获取的内容),我将获得(4) [true, null, false, {…}]的列表(最后一个项目最终就是我所需要的)。

由于这个原因,我在访问实际Axios请求的内容时遇到了问题(即使它始终是列表的最后一项)。只有执行{this.props.address.slice(-1)[0].href}才能访问返回的JSON项。我猜这不是应该的样子,所以我一定做错了。

我对React还是很陌生,因此我对使用Redux的不同方式并不熟悉。但是,当我使用reduxjs/toolkit中的createSlice时,已将其缩减为在初始状态下发生的事情(以前没有使用过,但是当前正在使用的主题正在使用它,因此我正在尝试复制他们的设置方式。

我已附上以下代码,感谢您提出的正确指导。我的文件比这些文件多得多-但我很确定这三个文件可以解决问题。

Research.js

import React from "react";
import { connect } from "react-redux";
import { fetchAddress } from "./_redux/addressActions";

class Research extends React.Component {
  componentDidMount() {
    this.props.fetchAddress(this.props.match.params.id);
  }

  render() {
    console.log(this.props.address);

    return <h1>{this.props.address.slice(-1)[0].href}</h1>;
  }
}

const mapStateToProps = (state) => {
  return {
    address: Object.values(state.address),
  };
};

export default connect(mapStateToProps, { fetchAddress })(Research);

addressSlice.js

import { createSlice } from "@reduxjs/toolkit";

const initialAddressState = {
  initialState: true,
};

export const callTypes = {
  list: "list",
  action: "action",
};

export const addressSlice = createSlice({
  name: "addresses",
  initialState: initialAddressState,
  reducers: {
    addressFetched: (state, action) => {
      state.actionsLoading = false;
      state.address = action.payload.address;
      state.error = null;
    },
  },
});

addressAction.js

import * as requestFromServer from "./addressCrud";
import { addressSlice, callTypes } from "./addressSlice";

const { actions } = addressSlice;

export const fetchAddress = (id) => (dispatch) => {
  if (!id) {
    return dispatch(actions.addressFetched({ address: undefined }));
  }

  dispatch(actions.startCall({ callType: callTypes.action }));
  return requestFromServer
    .getAddress(id)
    .then((response) => {
      const address = response.data;
      dispatch(actions.addressFetched({ address: address }));
    })
    .catch((error) => {
      error.clientMessage = "Can't find address";
      dispatch(actions.catchError({ error, callType: callTypes.action }));
    });
};
javascript reactjs redux react-redux redux-saga
1个回答
0
投票

编辑答案:更加清晰。

我找不到任何记录redux工具箱来处理您应用程序的加载状态。如果您自行设置该加载状态怎么办,类似于他们在文档https://redux-toolkit.js.org/usage/usage-guide#asynchronous-logic-and-data-fetching中的加载状态。

需要处理减速器中的负载。

export const addressSlice = createSlice({
  name: "addresses",
  initialState: initialAddressState,
  reducers: {
    addressLoading: (state, action) => {
      state.loading = true;
    },
    addressFetched: (state, action) => {
      if(state.loading) {
        state.loading = false;
        state.address = action.payload.address;
        state.error = null;
      }
    },
  },
});

然后确保调度该事件以指示已开始加载。

dispatch(actions.addressLoading());
  return requestFromServer
    .getAddress(id)
    .then((response) => {
      const address = response.data;
      dispatch(actions.addressFetched({ address: address }));
    })

我还将在初始状态下始终包含合理的默认值。

const initialAddressState = {
  loading: false,
  error: null,
  address: null
};

最后一步是避免渲染,如果我们正在加载或没有数据。还有很多方法可以做到这一点。在不查看应用程序其余部分的情况下很难知道您的最佳选择。

render() {
  console.log(this.props.address);
  if(this.props.loading || this.props.address === null) return null;
  return <h1>{this.props.address.href}</h1>;
}

更接近问题的希望。

编辑答案:我最初误解了这个问题。

const mapStateToProps = (state) => {
  return {
    address: Object.values(state.address),
  };
};

这将从state.address对象中创建一个值数组。因此,在这种情况下,对象看起来像这样:

const obj = { first: true, second: false };
const oops = Object.values(obj);

console.log(oops); // [true, false]

我不确定您希望数据如何显示,但是如果要使用地址对象,则将其分配为address: state.address

原始答案:通常,在JavaScript中,我们像这样访问数组的最后一项。您可以通过创建指向address的局部变量来缩短它。

const address = this.props.address;
address[address.length - 1];

在您的示例中,您正在获取数组的最后一个元素(切片使您可以使用负数从末尾回到中间)并将其切成自己的数组。之后,您可以使用[0]将其作为新数组的第一个元素进行访问。

我认为根据您想要的描述,进行最后一个项目访问是合理的。

© www.soinside.com 2019 - 2024. All rights reserved.