构建一个模式组件,该组件从应用程序的任何部分打开引导模式,然后为该组件的外部设置自定义状态。它工作正常,但是当我打开模式,我似乎无法弄清楚我永远只是得到这个错误的原因:在组件外部设置组件状态会导致错误
警告:的setState(...):现有的状态转变(如内中无法更新
render
或另一个组件的构造函数)。渲染方法应该是道具和状态的纯粹功能;构造函数的副作用是一个反模式,但可以移动到componentWillMount
.`不真正打破任何东西,但错误一直显示出来。
我的代码:
layout.js
import React from "react";
import {Link} from 'react-router';
import NotificationSystem from 'react-notification-system';
import AppHeader from "#/ui/header/AppHeader";
import AppFooter from "#/ui/footer/AppFooter";
import Modal from "#/ui/modals/modal/Modal";
import "@/main.scss";
import './layout.scss';
export default class Layout extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
app.notify.clear = this.refs.notificationSystem.clearNotifications;
app.notify = this.refs.notificationSystem.addNotification;
app.modal = this.refs.modal.updateProps;
}
render() {
return (
<div class="app">
<div class="header">
<AppHeader page={this.props.location.pathname.replace('/', '')}/>
</div>
<div class="body">
{this.props.children}
</div>
<div class="footer">
<AppFooter />
</div>
<NotificationSystem ref="notificationSystem" style={false} />
<Modal ref="modal" />
</div>
);
};
}
Modal.js
import React from "react";
import ReactDOM from 'react-dom';
import SVGInline from "react-svg-inline";
import {closeSvg} from '#/utils/Svg';
export default class Modal extends React.Component {
constructor(props) {
super(props);
this.state = {
showHeader: true,
showFooter: false,
title: "",
size: '',
className: '',
id: '',
footerContent: null,
showSubmitBtn: true,
showCancelBtn: true,
cancelBtnText: "Cancel",
successBtnText: "Save Changes",
onModalClose:() => {},
showModal: false,
html:() => {}
}
this.updateProps = this.updateProps.bind(this);
this.hideModal = this.hideModal.bind(this);
}
componentWillMount() {
var self = this;
var $modal = $(ReactDOM.findDOMNode(this));
}
componentDidUpdate(prevProps, prevState) {
if(this.state.showModal) {
$('body').addClass('modal-open');
} else {
$('body').removeClass('modal-open');
}
}
componentWillUnmount() {
// $('body').removeClass("modal-open");
}
componentWillReceiveProps(nextProps) {
console.log(nextProps);
}
updateProps(args) {
let merged = {...this.state, ...args};
this.setState(merged);
}
hideModal() {
this.setState({
showModal: false
});
this.state.onModalClose();
}
buildFooter() {
if(this.props.footerContent) {
return (
<div class="content">
{this.props.footerContent}
</div>
)
} else if(this.props.showCancelBtn && this.props.showSubmitBtn) {
return (
<div class="buttons">
<button type="button" class="btn btn-default" data-dismiss="modal" onClick={this.props.onModalClose}>{this.props.cancelBtnText}</button>
<button type="button" class="btn btn-success">{this.props.successBtnText}</button>
</div>
);
} else if(this.props.showCancelBtn) {
return (<button type="button" class="btn btn-default" data-dismiss="modal" onClick={this.props.onModalClose}>Close</button>);
} else if(this.props.showSubmitBtn) {
return (<button type="button" class="btn btn-success">Save changes</button>);
}
}
render() {
let {
id,
className,
onModalClose,
size,
showHeader,
title,
children,
showFooter,
showModal,
html
} = this.state;
return (
<div class={`modal-wrapper`} >
{
showModal ?
<div class={`modal fade in ${className}`} role="dialog">
<div class="bg" ></div>
<div class={`modal-dialog ${size}`}>
<div class="modal-content">
{ showHeader ?
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<SVGInline svg={closeSvg} />
</button>
<h4 class="modal-title">{ title }</h4>
</div> : '' }
<div class="modal-body" >
{html()}
</div>
{ showFooter ?
<div class="modal-footer">
{ this.buildFooter() }
</div> : ''
}
</div>
</div>
</div>
: ''
}
</div>
);
}
}
SelectDefaultImage.js
import React from "react";
import sass from "./selectdefaultimage.scss";
import FullScreenImageModal from "#/ui/modals/fullscreenimagemodal/FullScreenImageModal";
export default class SelectDefaultImage extends React.Component {
constructor() {
super();
this.state = {
showModal: false,
imgUrl: false,
}
}
showImageModal(image) {
this.setState({
showModal: true,
imgUrl: image
});
}
hideImageModal() {
this.setState({
showModal: false,
imgUrl: false
})
}
onSelectImageClick(e, image) {
$('.select-image-widget .active').removeClass('active');
$(e.target).parent().addClass('active');
// this.props.selectedImage(image)
}
render() {
let {listingManager, images, selectedImage} = this.props;
let {imgUrl} = this.state;
return (
<div class="content">
<div class="row">
<div class="col-sm-12">
<label class="control-label" for="description">Select an Image</label>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="select-image-widget">
{
images.map((image, idx) => {
return (
<div class="selecter" key={idx}>
<div class="img" style={{backgroundImage: `url(${listingManager.LISTINGS_PATH + image})` }} onClick={(e) => { this.onSelectImageClick(e, image) }}></div>
<i class="fa fa-search-plus" aria-hidden="true" onClick={()=> {this.showImageModal(image)}}></i>
</div>
)
})
}
</div>
</div>
</div>
{
this.state.showModal ?
app.modal({
showModal: true,
className: "fullscreen-image-modal",
size: "modal-lg",
html:() => {
return (<img src={listingManager.LISTINGS_PATH + imgUrl} />);
}
})
: ''
}
</div>
)
}
}
问题中的代码似乎没有任何可能导致上述错误的问题。你包括了一切吗?另一方面,由于您正在导入外部库,因此这个错误可能来自其中一个库。 –
尽管不直接与问题相关,但尽量避免使用jquery进行反应。如果你认为你需要jQuery,那意味着你没有做出正确的反应。 https://reactjs.org/docs/thinking-in-react.html –
@PubuduDodangoda只有当showModal设置为true时,错误才在Modal.js中。只有在模态显示后才会发生。我已包含与此问题相关的所有代码。我被困在自己身上,并且一直呆在现在4个小时...... – Shivam