反应:不正确的Modal组件在axios调用后被渲染

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

我从react-semantic-ui中获取了一个模态组件,并将其配置为具有类似对话框的确认/警告或传统模态。

我这样做主要是为了练习制作更多有用和可重用的组件,并间接地练习管理状态并将其移动到商店,即redux ...

import React, { Component } from 'react'
import { Button, Modal } from 'semantic-ui-react'
import PropTypes from 'prop-types'

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { logOutUser  } from '../../store/reducers/users/index'
import { modalStateOn, modalStateOff  } from '../../store/reducers/ui/index'


class MyModal extends Component {

 close = () => {
  const { modalStateOff } = this.props
  modalStateOff();
 }

 logOutUser = () => {
  const { logOutUser } = this.props
  logOutUser()
 }

 render() {
  const { modalActive } = this.props

   return (
    <>
      <Modal dimmer={'blurring'} centered={true} size={'mini'} open={modalActive} onClose={this.close}>
        <Modal.Header>
         <p>{this.props.message}</p>
        </Modal.Header>
        <Modal.Actions>
         {this.props.isAlertModal ?
         <Button
          color='black'
          onClick={this.close}
          content={this.props.affirmativeUsed}
         />
         :
        <>
         <Button
           color='black'
           onClick={this.close}
          >
           No
          </Button>
          <Button
           positive
           icon='checkmark'
           labelPosition='right'
           content={this.props.affirmativeUsed}
           onClick={() => { this.close(); this.logOutUser() }}
          />
        </>
         }
        </Modal.Actions>
      </Modal>
    </>
   )
 }
}

MyModal.propTypes = {
 message: PropTypes.string,
 affirmativeUsed: PropTypes.string
}

function mapStateToProps(state) {
 const { ui } = state
 const { modalActive } = ui

 return { modalActive }
}
const mapDispatchToProps = dispatch =>
 bindActionCreators({ logOutUser, modalStateOn, modalStateOff }, dispatch)

export default connect(mapStateToProps, mapDispatchToProps)(MyModal)

这对于我想用于注销的模态非常有效:

=======================================
home | profile | *dashboard | logout          /* You get a Modal to confirm your desire to log out */
=======================================

[但是,在我的个人资料页面上,我创建了一个ImageUploader组件来处理该页面的加载图像,正如您现在可能已经猜到的,我希望axios请求成功时也弹出一个Modal,并且未能提供一些反馈...

=======================================
home | *profile | dashboard | logout          /* You get a Modal to confirm your desire to log out */
=======================================

        -------------
       | choose file |                       /* AND!!! Get a Modal to confirm with a success OR failure!!
        -------------

这是ImageUploader组件:

import React, { Component } from 'react';
import './ImageUploader.css';
import FooModal from '../Modal/MyModal' 
import axios from 'axios';

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { loadAvatar } from '../../store/reducers/users/index'
import { modalStateOn, modalStateOff } from '../../store/reducers/ui/index'

class ImageUploader extends Component {
 constructor(props) {
  super(props);
    this.uploadImage = this.uploadImage.bind(this);
 }

 componentDidUpdate(previousProps, previousState) {
  if (previousProps.userAvatar !== this.props.userAvatar) {
  console.log("this.props.userAvatar in componentDidUpdate", this.props.userAvatar);
   loadAvatarImage(this.props.userAvatar)
  }
 }

 setDefaultImage(){
  var defaultImage =  '../../static/profile-avatars/assets/default-img.jpg';
  this.loadAvatarImage(defaultImage)
 }

 loadAvatarImage(img) {
  var { loadAvatar } = this.props;
  loadAvatar(img)
 }

 uploadImage(e, method) {

  const { modalStateOn } = this.props
  console.log('this.props in ImageUploader uploadImageFunction', this.props)

  if (method === "multer") {

   let imageFormObj = new FormData();

   imageFormObj.append("imageName", "multer-image-" + Date.now());
   imageFormObj.append("imageData", e.target.files[0]);

   this.loadAvatarImage(window.URL.createObjectURL(e.target.files[0]))

   var config = { headers: { 'content-type': 'multipart/form-data' }}
   axios.post(`http://localhost:8016/images/uploadmulter`, imageFormObj, config )
    .then((data) => {
     if (data.data.success) {
      console.log("data ", data);
      modalStateOn();
     return (
       <FooModal
       isAlertModal={true}
       open={true}
       affirmativeUsed="Yes"
       message="Your image has been uploaded succesfully"
      />
     )
     }
    })
    .catch((err) => {
     alert("Error while uploading image using multer");
      this.setDefaultImage();
    });
  }
    e.stopPropagation();

 }

 render() {
  var {  userAvatar } = this.props
  return (
   <>
    <div className="main-container">
     <h3 className="main-heading">Image Upload App</h3>

     <div className="image-container">
      <div className="process">
       <h4 className="process__heading">Process: Using Multer</h4>
       <p className="process__details">Upload image to a node server, connected to a MongoDB database, with the help of multer</p>
       <form action="/uploadmulter" method="post" encType="multipart/form-data" >
        <input type="file" name="avatar" className="process__upload-btn"
         onChange={(e) => {
          this.uploadImage(e, "multer");
        }} />
        <img src={userAvatar} alt="upload-image" className="process__image" />
       </form>
      </div>
     </div>
    </div>
  </>
  );
 }
}

function mapStateToProps(state) {
 const { ui, users } = state
 const { userAvatar } = users
 const { modalActive } = ui

 return { userAvatar, modalActive }
}

const mapDispatchToProps = dispatch =>
 bindActionCreators({ loadAvatar, modalStateOn }, dispatch)

export default connect(mapStateToProps, mapDispatchToProps)(ImageUploader)

有趣的是,注销操作呈现的是Modal,而不是ImageUploader中的一个?

AND

当我将prop值传递给isAlertModal时,它会被忽略吗?!

  <FooModal
   isAlertModal={true}
   open={true}
   affirmativeUsed="Yes"
   message="Your image has been uploaded succesfully"
  />

所以我想也许我必须在导航中卸载Modal才能允许图像加载器Modal传播?

*请注意uploadImage函数中已调用[C​​0],但没有骰子!

任何帮助将不胜感激!

javascript reactjs axios react-props semantic-ui-react
1个回答
2
投票

您的e.stopPropagation();应该处于渲染功能,而不是回调函数。

每次状态或道具更改时都会调用render函数。因此,您应该在状态FooModal或类似状态下设置一个标志,并将其用作呈现isUploaded的条件。

关于post方法的回调函数,您只需更新状态。它将以新状态再次触发渲染功能。

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