反应ImageUploadContainer组件绑定数据可以正常工作,但是会收到javascript错误“未捕获的TypeError:无法读取null的属性'imagePreviewUrl'”
该操作似乎工作正常,并且可以很好地提取图像数据,但我不知道为什么会发生此错误。
它是由redux和react构建的。
ImageUploadConatiner.js(儿童)
import React, {Component} from 'react'
import {bindActionCreators} from 'redux'
import { FormattedMessage } from 'react-intl'
import {getFile} from '../../../selectors/qna'
import {connect} from 'react-redux'
import classnames from 'classnames'
import { getLocale } from '../../../selectors/session'
import actions from '../../../actions/qna/form'
import FormGroup from 'react-bootstrap/lib/FormGroup'
import ControlLabel from 'react-bootstrap/lib/ControlLabel'
export const mapStateToProps = (state) => {
const file = getFile(state);
let isMobile = true;
if(typeof window !== 'undefined' && window.innerWidth >= 992)
isMobile = false;
return {
file,
isMobile,
imageUrl: undefined,
locale: getLocale(state)
}
};
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators({
...actions
}, dispatch)
}
};
export const mergeProps = (mappedProps,dispatchProps) => {
return Object.assign(mappedProps,{
actions: {
imageUpdate: (idx,file,imagePreviewUrl) => {
dispatchProps.actions.qnaFormFileUpdate({ idx, file, imagePreviewUrl })
},
imageDelete: (idx) => {
dispatchProps.actions.qnaFormFileDelete({ idx: idx.num })
}
}
})
}
@connect(mapStateToProps, mapDispatchToProps,mergeProps)
export default class ImageUpload extends Component {
constructor(props){
super(props);
this.state = {
};
this._handleImageChange = this._handleImageChange.bind(this)
}
_handleImageChange(e) {
e.preventDefault()
const { actions, file } = this.props;
const fileCount = Object.keys(file).length;
let reader = new FileReader();
let imageFile = e.target.files[0];
reader.onloadend = (upload) => {
actions.imageUpdate(fileCount, imageFile, reader.result)
};
if (imageFile)
reader.readAsDataURL(imageFile);
this.input.value = null
}
componentDidMount() {
const { actions, imageUrl } = this.props;
if(imageUrl !== undefined && imageUrl) {
actions.imageUpdate({ file: null, imagePreviewUrl: imageUrl })
}
}
render() {
const { actions, file, locale } = this.props;
let $imagePreview = [];
const fileCount = Object.keys(file).length;
if (file !== undefined) {
for (let num in file) {
if (file[num].imagePreviewUrl != null) {
$imagePreview[num] = (
<div className='qna-file-input-delete-container' key={`qnaPreview-${num}`}>
<div className='qna-file-input-delete-btn'>
<button className='qna-file-delete-btn'
onClick={(e) => {
e.preventDefault();
actions.imageDelete({num})
}}>
<i className={ classnames('fa fa-times-circle-o', {'fa-1x': this.props.isMobile}, {'fa-2x': !this.props.isMobile}) }/>
</button>
</div>
<img src={file[num].imagePreviewUrl}/>
</div>
);
}
}
}
return (
<div>
<FormGroup controlId="formHorizontalType">
<ControlLabel><FormattedMessage id={`${locale}.user.qna.attachImage`}/></ControlLabel>
{ fileCount < 10 ?
<button className="button button-outline button-sm" style={{width: '160px', marginBottom: '16px', display: 'block'}}
onClick={(e) => {
e.preventDefault();
if (this.input) {
this.input.click();
}
}}>
<FormattedMessage id={`${locale}.user.qna.selectImage`}/>
</button>
: undefined
}
<div style={{color:'#ff4949'}}><FormattedMessage id={`${locale}.user.qna.limitMessage`}/></div>
<div className="qna-file-input-controls">
<input style={{display: 'none'}} type="file"
ref={(ref) => {
this.input = ref
}}
accept='.gif, .jpg, .png, .jpeg, .bmp'
onChange={this._handleImageChange}/>
{$imagePreview}
</div>
</FormGroup>
</div>
)
}
}
QnaContainer.js(父母)
import React, {Component} from "react";
import _, {union} from 'lodash'
import {FormattedMessage, FormattedHTMLMessage, FormattedDate, FormattedTime, injectIntl} from 'react-intl'
import ProgressBar from "../../../components/ProgressBar";
import Select from "../../../components/select/Select";
import HelmetContainer from './HelmetContainer';
import ListSectionContainer from '../../../containers/faq/ListSectionContainer'
import ImageUpload from "./ImageUploadContainer";
import {getLocale} from "../../../selectors/session";
import {getQnAForm, getQnAFormPayment} from "../../../selectors/qna";
import {getOrderByOrderNo, getOrderNos} from "../../../selectors/user/order/index";
import {getFAQ} from "../../../selectors/about";
import {getLock} from "../../../selectors/share";
import {bindActionCreators} from "redux";
import actions from "../../../actions/qna/form";
import uiActions from "../../../actions/ui";
import shareActions from "../../../actions/share";
import {asyncConnect} from "redux-connect";
import {startUp as qnaFormStartUp} from "../../../sagas/qna/form";
import moment from "moment-timezone";
import {ICONS} from "../../../constants/Icons";
import Icon from "../../../components/Icon";
import Dialog from "../../../components/dialog/Dialog";
import { Link } from 'react-router'
export const mapStateToProps = state => {
const locale = getLocale(state)
const QnAForm = getQnAForm(state)
const faq = getFAQ(state)
const orderNos = getOrderNos(state)
const isLockSubmit = getLock(state, 'QnA', 'submit')
(...)
return {
faq,
locale,
day,
koreaTime,
holidays,
isOpen,
orderList,
formState: QnAForm.formState,
typeValue: QnAForm.type,
paymentValue: QnAForm.payment,
subjectValue: QnAForm.subject,
contentValue: QnAForm.content,
isFetching: QnAForm.isFetching,
isPayment: getQnAFormPayment(state),
isConfirm: state.share.confirm,
links: {
primary: '/faq'
}
}
}
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators({
...actions, ...uiActions, ...shareActions
}, dispatch)
}
}
export const mergeProps = (mappedProps, dispatchProps) => {
return Object.assign(mappedProps, {
actions: {
typeChange: (e) => {
dispatchProps.actions.qnaTypeSelect(e)
},
listChange: (e) => {
dispatchProps.actions.qnaPaymentSelect(e)
},
subjectTextUpdate: (e) => {
dispatchProps.actions.qnaSubjectTextUpdate(e)
},
contentTextUpdate: (e) => {
dispatchProps.actions.qnaContentTextUpdate(e)
},
submit: () => {
if (!mappedProps.isLockSubmit) {
dispatchProps.actions.generalBtnLock('QnA', 'submit')
dispatchProps.actions.qnaSubmitRequest()
}
}
}
})
}
@asyncConnect([{
promise: ({store: {runSaga}, helpers: {client}}) => {
const task = runSaga(qnaFormStartUp, client)
return task.done
}
}], mapStateToProps, mapDispatchToProps, mergeProps)
@injectIntl
export default class QnaContainer extends Component {
constructor(props) {
super(props)
this.state = {
alert: false,
categoryValue: '',
}
}
render() {
const { locale, actions, faq, links: {primary}, intl} = this.props;
return (
(...)
<div className="field">
<ImageUpload />
</div>
(...)
);
}
}