アプリケーションの任意の部分からブートストラップモーダルを開き、外部のコンポーネントのカスタム状態を設定するモーダルコンポーネントを構築します。正常に動作しますが、私はモーダルを開くと常にこのエラーが発生します。理由はわかりません:コンポーネント外のコンポーネント状態を設定すると、エラーが発生する
警告:setState(...):既存の状態遷移中には更新できません
render
または別のコンポーネントのコンストラクタ)。レンダリング方法は、小道具と州の純粋な機能でなければなりません。コンストラクタの副作用はアンチパターンですが、componentWillMount
に移動することができます。 `doesntは本当に何かを壊しますが、エラーは表示され続けます。
マイコード:
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>
)
}
}
問題のコードは、上記のエラーを引き起こす可能性のある問題はないようです。すべてを含めましたか? 一方、外部ライブラリをインポートしているため、このエラーの1つが原因で発生している可能性があります。 –
そして、直接質問には関係しませんが、反応とjqueryの使用を避けるようにしてください。 jqueryが必要だと思うなら、それはあなたが正しい方法で反応していないことを意味します。 https://reactjs.org/docs/thinking-in-react.html –
@ PubuduDodangoda showModalがtrueに設定されている場合のみ、Modal.jsにエラーがあります。モーダルが表示された後にのみ発生します。 Iveには、この問題に関連するすべてのコードが含まれています。私は自分で立ち往生していて、今は4時間ぐらいです。 – Shivam