【问题标题】:React Loading Spinner + Redux?反应加载微调器+ Redux?
【发布时间】:2018-10-12 11:17:14
【问题描述】:

UploadImage 组件是一个哑组件。它获取调用上传的 redux 操作,并获取图像文件路径,一旦图像启动,该操作将其放入适当的 reducer。这里它与两个道具一起使用:

<UploadImage onUpload={this.props.uploadNewArticleImage} image={this.props.newArticleBuffer.image}/>

我的newArticleBuffer-reducer 有image: null,上传完成后会得到图片的路径。发生这种情况时,我的组件会做出反应,不再显示微调器。

在内部,UploadImage 如下所示:

import React, { Component } from 'react';

export default class UploadImage extends Component {
  constructor(props) {
    super(props);

    this.state = { file: "", loading: false};

    this.onSubmit = this.onSubmit.bind(this);
    this.onFileChange = this.onFileChange.bind(this);    
  }

  onSubmit(e) {
    e.preventDefault();
    this.setState({loading: true});
    this.props.onUpload(this.state.file);
  }

  onFileChange(event) {
    this.setState({ file: event.target.files[0]});
  }

  render() {    
    let spinner = <div>Not Loading</div>
    if(this.props.image == null && this.state.loading) {
      spinner = <div>Loading</div>;
    }

    return (
      <div>Image Upload Component
      <input 
        type="file" 
        accept="image/*"
        onChange={this.onFileChange} />

      {spinner}
       <button onClick={(e) => this.onSubmit(e)}>Upload Image</button>
      </div>
    );
  }
}

有几个问题。首先,我从未将“加载”设置回false:当 Redux 操作完成时,我需要以某种方式执行此操作,但我不知道如何执行此操作。

其次,更重要的是,当用户上传图片但随后决定上传其他文件时,这种方法将不起作用。 image 将不再是 null

【问题讨论】:

  • 使用 redux-thunk
  • 我已经是了。您认为这将如何解决问题?

标签: javascript reactjs redux react-redux


【解决方案1】:

首先,将 UploadImage 组件连接到 redux 存储。

然后,在您的操作文件中创建一些操作:

// You only need to export and call this action from your component:
export const uploadNewArticleImage = (uploadData) => {
    return (dispatch) => {
        dispatch(uploadNewArticleImageLoading(true));   // set isLoading = true

        fetch('uploadData.url', {
            method: 'POST',
            body: uploadData.data,
            etc...
        })
            .then((response) => dispatch(uploadNewArticleImageLoading(false)))  // response received
            .then((response) => response.JSON())
            .then((jsonObj) => dispatch(uploadNewArticleImageSuccess(jsonObj.image))) // success
            .catch((error) => dispatch(uploadNewArticleImageLoading(false));          // error
    };
};

const uploadNewArticleImageLoading = (isLoading) => {
    return {
        type: "UPLOAD_NEW_ARTICLE_IMAGE_LOADING",
        payload: {
            isLoading: isLoading
        }
    };
};

const uploadNewArticleImageSuccess = (image) => {
    return {
        type: "UPLOAD_NEW_ARTICLE_IMAGE_SUCCESS",
        payload: {
            image: image
        }
    };
};

然后在你的 reducer 中,处理更新 store 的操作。

这样,每当我们收到来自服务器的响应,或者在图片上传过程中出现错误时,isLoading 就会被设置为 false。

【讨论】:

  • 问题,真的有必要为每个单独的组件单独加载布尔值吗?我宁愿只在 rootReducer 上设置一个全局 isLoading 状态并分派到那里。
  • @tshm001 没有必要为每个单独的组件设置一个
【解决方案2】:

我所拥有的是在 Redux 中我有一个 PageState 对象,它上面有各种共享属性,其中之一是 isProcessing。每当有ajax调用时,另一个名为processingCount的属性就递增,然后将isProcessing设置为processingCount &gt; 0

每当 ajax 请求完成或失败时,processingCount 属性就会递减。

然后,您的 PageState 对象可以在 Spinner 组件中使用,可以附加到 Button 以在处理正在进行时停止禁用它们,或者您可以在整个应用程序中显示各种加载动画。

因此,在您的代码中,我将删除所有组件状态,并将其移动到您的 Redux 存储中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 2019-11-16
    • 2022-01-20
    • 2017-07-29
    • 1970-01-01
    • 2020-07-05
    • 2021-01-17
    相关资源
    最近更新 更多