3

我是反应 redux 的新手。我想在用户按下搜索按钮时添加加载文本,并在数据返回或操作完成时关闭文本。在正常的异步函数中,我可以在回调之前和之后切换 isLoading 标志。

但是,在我的应用程序中,我正在调度一个返回“类型”和“有效负载”的操作,这是一个承诺。中间件 redux-promise 然后“自动”转换该承诺有效负载并将其发送到减速器。换句话说,中间件在幕后为 Promise 执行 .then 操作,并为我的 reducer 提供正确的数据。

在这种情况下,我不确定如何将加载文本添加到我的视图中,因为一旦我调用 this.props.getIdByName(this.state.value),我不知道数据何时返回。对我来说,合乎逻辑的地方是在 reducer 内,因为那是数据返回的时候。但是,我相信这将是一个坏方法,因为减速器不应该执行这样的任务?

在我的组件中,我的提交具有以下功能

  handleSubmit(e) {
    e.preventDefault();
    this.props.getIdByName(this.state.value);
  }

在我的 actions/index.js 文件中,我有以下动作生成器

export function getIdByName(name) {
    const FIELD = '/characters'
    let encodedName = encodeURIComponent(name.trim());
    let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH + '&name=' + encodedName;
    const request = axios.get(searchUrl)

    return {
        type: GET_ID_BY_NAME,
        payload: request
    }
}

在我的 reducers/reducers.jsx 里面

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case GET_ID_BY_NAME: 
            console.log(action.payload.data.data.results[0].id); <-- here the data comes back correctly because reduer called the promise and gave back the data for me
            return {...state, id: action.payload.data.data.results[0].id};
        default:
            return state;
    }
}

在我的主 index.js 文件中,我使用以下中间件创建了商店

const createStoreWithMiddleware = applyMiddleware(
    promise,
    thunk
)(createStore);
4

2 回答 2

1

我相信佩德罗的回答应该让你开始,但我最近loader/pre-loader在我的应用程序中做了非常准确的事情。

最简单的方法是。

  1. state在您的一个减速器中的对象中创建一个新键并调用它showLoader: false
  2. 在与之前相同的容器中(带有按钮的容器),创建一个mapStateToProps并获取该 state 属性showLoader
  3. container包含您尝试触发loaderwith 的按钮的内部,添加一个onClick调用 的事件action,例如displayLoader。在同一函数中还设置this.props.showLoadertrue
  4. 创建一个displayLoader动作写这样的东西:

    function displayLoader() {
        return {
            type: DISPLAY_LOADER,
            payload: {}
        }
    }
    
  5. 在减速器中,捕获此操作并将showLoader返回设置为收到false所需的时间。payload

希望能帮助到你!

于 2017-08-10T23:44:43.067 回答
1

Promise当您在使用 时以 a作为其有效负载分派一个动作时redux-promiseredux-promise中间件将捕获该动作,等到Promise解析或拒绝,然后重新分派该动作,现在将 . 的结果Promise作为其有效负载。这意味着您仍然可以处理您的操作,并且一旦您处理它,您就知道它已经完成了。所以你是对的,reducer 是处理这个问题的正确地方。

但是,您也说得对,减速器不应该有副作用。他们应该只建立新的状态。因此,答案是通过在 Redux 中更改应用程序的状态来显示和隐藏加载指示器:)

isLoading我们可以向我们的 Redux 存储添加一个名为的标志:

const reducers = {
    isLoading(state = false, action) {
        switch (action.type) {
          case 'START_LOADING':
            return true;
          case 'GET_ID_BY_NAME':
            return false;
          default:
            return state;
        }
    },
    // ... add the reducers for the rest of your state here
}

export default combineReducers(reducers);

每当你要调用时,在调用它之前getIdByName调度一个带有 type 的动作。'START_LOADING'getIdByName由 重新调度时redux-promise,您将知道加载完成并且isLoading标志将设置回 false。

现在我们有一个标志来指示我们是否在 Redux 存储中加载数据。使用该标志,您可以有条件地呈现加载指示器。:)

于 2017-04-27T17:13:57.963 回答