#javascript #reactjs #react-native
#javascript #reactjs #react-native
Вопрос:
Я использую URL.createObjectURL
для создания изображения и передачи его другому компоненту. В моем NotificationStepper URL.createObjectURL
работает просто отлично, но в другом компоненте Createwebsite я получаю эту ошибку TypeError: не удалось выполнить ‘createObjectURL’ на ‘URL’: не найдена функция, соответствующая предоставленной подписи.. ниже приведен мой компонент NotificationStepper.
const styles = {
transparentBar: {
backgroundColor: 'transparent !important',
boxShadow: 'none',
paddingTop: '25px',
color: '#FFFFFF'
},
dialogPaper: {
minHeight: '400px',
maxHeight: '400px',
},
};
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const useStyles = makeStyles((theme) =>
createStyles({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}),
);
function getSteps() {
return ['Create', 'Audience', 'Timing'];
}
function getStepContent(step, $this) {
return (
<div className="row">
<CardBox styleName="col-lg-12"
heading="">
<form className="row" noValidate autoComplete="off" style={{ "flex-wrap": "no-wrap", "flex-direction": "column" }}>
<div className="col-md-12 col-12" style={{ "margin-bottom": "15px", "display": "flex", "align-items": "center" }}>
<Tooltip title="Use featured image of the landing page here. Works on Chrome, Opera, Edge. Recommended aspect ratio 2:1. Jpg, Jpeg, PNG file types only.">
<IconButton aria-label="">
<HelpOutlineIcon />
</IconButton>
</Tooltip>
<span style={{ "width": "20%", "margin-right": "20px" }}>Banner: </span>
<div className="inputfile">
Upload
<input className='hide_file' type="file" onChange={$this.onBannerChange} />
</div>
{$this.state.banner ?
<span>{$this.state.icon.banner}</span>
: null
}
</div>
</form>
</div >
);
}
class NotificationStepper extends React.Component {
state = {
banner: '',
crop: { x: 0, y: 0 },
zoom: 1,
aspect: 1,
croppedAreaPixels: null,
croppedImage: null,
showDialog: false,
};
onBannerChange = event => {
this.setState({ banner: event.target.files[0] });
this.setState({showDialog: true})
};
onIconChange = event => {
this.setState({ icon: event.target.files[0] });
this.setState({showDialogIcon: true})
};
onCropChange = crop => {
this.setState({ crop })
};
onCropComplete = (croppedArea, croppedAreaPixels) => {
this.setState({croppedAreaPixels: croppedAreaPixels});
};
CropImageBanner = async ()=> {
const croppedImage = await getCroppedImg(
URL.createObjectURL(this.state.banner),
this.state.croppedAreaPixels,
0
);
this.setState({ banner: croppedImage });
this.closeDialog();
};
closeDialog = () => {
this.setState({showDialog: false});
}
onZoomChange = zoom => {
this.setState({ zoom })
};
render() {
const steps = getSteps();
const { activeStep } = this.state;
if (this.props.showSuccessMessage) {
console.log('dispatch');
setTimeout(() => {
this.props.hideMessage();
}, 100);
}
if (this.props.showMessage) {
console.log('dispatch');
setTimeout(() => {
this.props.hideCompaignAlert();
}, 100);
}
const { classes } = this.props;
return (
<div>
{this.state.banner ?
// <span>{$this.state.banner.name}</span>
<Dialog
classes={{paper: classes.dialogPaper }}
fullWidth={true}
maxWidth='sm'
open={this.state.showDialog}
onClose={this.closeDialog}
>
<DialogTitle>
</DialogTitle>
<DialogContent>
<div className="App-crop" >
<div className="crop-container-div">
<Cropper
image={URL.createObjectURL(this.state.banner)}
crop={this.state.crop}
zoom={this.state.zoom}
aspect={this.state.aspect}
onCropChange={this.onCropChange}
onCropComplete={this.onCropComplete}
onZoomChange={this.onZoomChange}
/>
</div>
<div className="controls">
<Slider
value={this.state.zoom}
min={1}
max={3}
step={0.1}
aria-labelledby="Zoom"
onChange={(e, zoom) => this.onZoomChange(zoom)}
/>
</div>
</div>
</DialogContent>
<DialogActions>
<Button onClick={() => this.closeDialog()} color="secondary">
Cancel
</Button>
<Button onClick={() =>
this.CropImageBanner()
} color="primary">
Crop
</Button>
</DialogActions>
</Dialog>
:
null
}
<Stepper className="MuiPaper-root-custom" activeStep={activeStep} orientation="vertical">
{steps.map((label, index) => {
return (
<Step key={label}>
<StepLabel>{label}</StepLabel>
<StepContent className="pb-3">
<Typography>{getStepContent(index, this)}</Typography>
<div className="mt-2">
<div>
<Button
disabled={activeStep === 0}
onClick={this.handleBack}
className="jr-btn"
>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={this.handleNext}
className="jr-btn"
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
</StepContent>
</Step>
);
})}
</Stepper>
{activeStep === steps.length amp;amp; (
// <Paper square elevation={0} className="p-2">
/*<Typography>All steps completed - youamp;quot;re finished</Typography>*/
<div>
<Button onClick={this.sendNotification} disabled={!this.isFormValid} color="primary" style={{ "align-self": "flex-end", "border": "1px solid", "margin-left": "10px", "margin-bottom": "40px" }} size="small" className="col-md-2 col-2">Create</Button>
<Button onClick={this.handleReset} color="primary" style={{ "align-self": "flex-end", "border": "1px solid", "margin-left": "10px", "margin-bottom": "40px" }} size="small" className="col-md-2 col-2" color="primary">Reset</Button>
)}
{this.props.showMessage amp;amp; NotificationManager.error(this.props.alertMessage) ?
<NotificationContainer /> : null
}
{this.props.showSuccessMessage amp;amp; NotificationManager.success(this.props.successMessage)}
<NotificationContainer />
</div>
);
}
}
const mapDispatchToProps = dispatch => ({
showCompaignAlert: (message) => dispatch(showCompaignAlert(message)),
CreateCampaign: (data) => dispatch(CreateCampaign(data)),
hideMessage: () => dispatch(hideMessage()),
hideCompaignAlert: () => dispatch(hideCompaignAlert()),
showCampaignLoader: () => dispatch(showCampaignLoader())
});
const mapStateToProps = state => ({
loader: state.Campaigns.loader,
allWebsites: state.Websites.allWebsites,
alertMessage: state.Campaigns.alertMessage,
showMessage: state.Campaigns.showMessage,
successMessage: state.Campaigns.successMessage,
showSuccessMessage: state.Campaigns.showSuccessMessage,
});
export default withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(withStyles(styles) (NotificationStepper)));
и ниже приведен мой веб-сайт CreateWebsite
import React from "react";
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import Slide from "@material-ui/core/Slide";
import DialogTitle from "@material-ui/core/DialogTitle";
import DialogContent from "@material-ui/core/DialogContent";
import DialogActions from "@material-ui/core/DialogActions";
import FormControl from "@material-ui/core/FormControl";
import TextField from "@material-ui/core/TextField";
import {connect} from "react-redux";
import {createWebsite, hideSuccessMessage, hideAlertCreateWebsite} from "../../../actions/Websites";
import {NotificationContainer, NotificationManager} from "react-notifications";
import InputAdornment from "@material-ui/core/InputAdornment";
import IconButton from "@material-ui/core/IconButton";
import getCroppedImg from "../Send Notification/cropImage";
import Cropper from "react-easy-crop";
import Slider from "@material-ui/core/Slider";
import {withStyles} from "@material-ui/core/styles";
const styles = {
transparentBar: {
backgroundColor: 'transparent !important',
boxShadow: 'none',
paddingTop: '25px',
color: '#FFFFFF'
},
dialogPaper: {
minHeight: '400px',
maxHeight: '400px',
},
};
class CreateWebsiteComponent extends React.Component {
state = {
title: '',
url: '',
logo: '',
showDialog: false,
crop: { x: 0, y: 0 },
zoom: 1,
aspect: 1,
croppedAreaPixels: null,
croppedImage: null,
};
handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
};
onFileChange = event => {
this.setState({ logo: event.target.files[0] });
this.setState({ showDialog: true})
};
createWebsite = (title, url, logo) => {
let temp = 'https://' url;
this.props.createWebsite({title, url , logo})
};
onCropChange = crop => {
this.setState({ crop })
};
onCropComplete = (croppedArea, croppedAreaPixels) => {
this.setState({croppedAreaPixels: croppedAreaPixels});
};
closeDialog = () => {
this.setState({showDialog: false});
};
onZoomChange = zoom => {
this.setState({ zoom })
};
CropImageBanner = async ()=> {
const croppedImage = await getCroppedImg(
URL.createObjectURL(this.state.logo),
this.state.croppedAreaPixels,
0
);
this.setState({ logo: croppedImage });
this.closeDialog();
};
render() {
if (this.props.showSuccessMessage) {
setTimeout(() => {
this.props.hideSuccessMessage();
}, 100);
}
if (this.props.showAlertCreateWebsite_) {
setTimeout(() => {
this.props.hideAlertCreateWebsite();
}, 100);
}
const { title, url, logo} = this.state;
const openDialog = this.props.openDialog;
const { classes } = this.props;
return (
<div>
<Dialog
classes={{paper: classes.dialogPaper }}
fullWidth={true}
maxWidth='md'
open={this.state.showDialog}
onClose={this.closeDialog}
>
<DialogTitle>
</DialogTitle>
<DialogContent>
<div className="App-crop" >
<div className="crop-container-div">
<Cropper
image={this.state.log}
crop={this.state.crop}
zoom={this.state.zoom}
aspect={this.state.aspect}
onCropChange={this.onCropChange}
onCropComplete={this.onCropComplete}
onZoomChange={this.onZoomChange}
/>
</div>
<div className="controls">
<Slider
value={this.state.zoom}
min={1}
max={3}
step={0.1}
aria-labelledby="Zoom"
onChange={(e, zoom) => this.onZoomChange(zoom)}
/>
</div>
</div>
</DialogContent>
<DialogActions>
<Button onClick={() => this.closeDialog()} color="secondary">
Cancel
</Button>
<Button onClick={() =>
this.CropImageBanner()
} color="primary">
Crop
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openDialog}
onClose={this.props.closeDialog}
>
<DialogTitle>
{"Create Website"}
</DialogTitle>
<DialogContent>
<FormControl className="w-100">
<TextField
style={{'margin-right': "10px"}}
className="col-md-11 col-11"
id="name"
label="Title"
value={this.state.title}
onChange={this.handleChange('title')}
margin="normal"
fullWidth
/>
<TextField
style={{'margin-right': "10px"}}
className="col-md-11 col-11"
id="name"
label="URL"
value={this.state.url}
onChange={this.handleChange('url')}
margin="normal"
fullWidth
InputProps={{
startAdornment: (
<InputAdornment className='positionEnd' position="start">
https://
</InputAdornment>
),
}}
/>
<div style={{"margin-top": "20px"}} className='col-md-11 col-sm-12 col-12 flex-class-custom'>
<span style={{"margin-right": "20px"}}>Icon: </span>
<div className="inputfile">
Upload
<input className='hide_file' style={{"width": "80%"}} type="file" onChange={this.onFileChange} />
</div>
{this.state.logo ?
<span>{this.state.logo.name}</span>
: null
}
</div>
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={this.props.closeDialog} color="secondary">
Cancel
</Button>
<Button onClick={() => this.createWebsite(title, url , logo)
} color="primary">
Create
</Button>
</DialogActions>
</Dialog>
{this.props.showAlertCreateWebsite_ amp;amp; NotificationManager.error(this.props.alertMessage)}
<NotificationContainer/>
{this.props.showSuccessMessage amp;amp; NotificationManager.success(this.props.successMessage)}
<NotificationContainer/>
</div>
)
}
}
const mapDispatchToProps = dispatch => ({
createWebsite: (payload) => dispatch(createWebsite(payload)),
hideSuccessMessage: () => dispatch(hideSuccessMessage()),
hideAlertCreateWebsite: () => dispatch(hideAlertCreateWebsite())
});
const mapStateToProps = state => ({
loader : state.Websites.loader ,
alertMessage : state.Websites.alertMessage ,
showAlertCreateWebsite_ : state.Websites.showAlertCreateWebsite_,
showSuccessMessage : state.Websites.showSuccessMessage,
successMessage : state.Websites.successMessage
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(withStyles(styles)(CreateWebsiteComponent));
// export default CreateWebsiteComponent;