我从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
函数中已调用[C0],但没有骰子!
任何帮助将不胜感激!
您的e.stopPropagation();
应该处于渲染功能,而不是回调函数。
每次状态或道具更改时都会调用render函数。因此,您应该在状态FooModal
或类似状态下设置一个标志,并将其用作呈现isUploaded
的条件。
关于post方法的回调函数,您只需更新状态。它将以新状态再次触发渲染功能。