[解決済み] React, Uncaught RangeError: 最大呼び出しスタックサイズを超えている
質問
私はreactで仕事をしていますが、基本的に私はツールチップを持つボタンを作りたいと思っています。マウスの入出時に見えるようにするために、cssのdisplayプロパティを変更しています。しかし、エラーが発生し、どうしたらいいかわかりません...。
以下は私のコードです。
import React from 'react';
import ReactDOM from 'react-dom';
import Style from 'style-it';
var Ink = require('react-ink');
import FontIcon from '../FontIcon/FontIcon';
var IconButton = React.createClass({
getInitialState() {
return {
iconStyle: "",
style: "",
cursorPos: {},
};
},
extend(obj, src) {
Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
return obj;
},
Tooltip(props) {
var style = {};
if (this.tooltipDisplay) {
style.display = "block";
} else if (!this.tooltipDisplay) {
style.display = "none";
};
return <div className="tooltip" style={style}>{_props.tooltip}</div>;
},
showTooltip(){
this.tooltipDisplay = true;
},
removeTooltip(){
this.tooltipDisplay = false;
},
render() {
var _props = this.props,
tooltip = this.Tooltip,
opts,
tooltipDisplay = false,
disabled = false,
rippleOpacity,
outterStyleMy = {
border: "none",
outline: "none",
padding: "8px 10px",
"background-color": "red",
"border-radius": 100 + "%",
cursor: "pointer",
},
iconStyleMy = {
"font-size": 12 + "px",
"text-decoration": "none",
"text-align": "center",
display: 'flex',
'justify-content': 'center',
'align-items': 'center',
},
rippleStyle = {
color: "rgba(0,0,0,0.5)",
};
if (_props.disabled || _props.disableTouchRipple) {
rippleStyle.opacity = 0;
};
this.setState({
iconStyle: _props.iconStyle
});
this.setState({
style: _props.style
});
if (_props.disabled) {
disabled = true;
};
if (this.state.labelStyle) {
iconStyleMy = this.state.iconStyle;
};
if (this.state.style) {
outterStyleMy = this.state.style;
};
if (_props.href) {
opts.href = _props.href;
};
var buttonStyle = this.extend(outterStyleMy, iconStyleMy);
return(
<Style>
{`
.IconButton{
position: relative;
}
.IconButton:disabled{
color: ${_props.disabledColor};
}
.btnhref{
text-decoration: none;
}
`}
<a {...opts} className="btnhref" >
<tooltip text={this.props.tooltip} position={this.options} />
<button ref="button" className={"IconButton" + _props.className} disabled={disabled} style={buttonStyle}
onMouseEnter={this.showTooltip} onMouseLeave={this.removeTooltip} >
<Ink background={true} style={rippleStyle} opacity={rippleOpacity} />
<FontIcon className={_props.iconClassName}/>
</button>
</a>
</Style>
);
}
});
ReactDOM.render(
<IconButton href="" className="" iconStyle="" style="" iconClassName="face" disabled="" disableTouchRipple="" tooltip="aaaaa" />,
document.getElementById('app')
);
コンソールでは、このエラーが表示されます。
Uncaught RangeError: Maximum call stack size exceeded
at defineRefPropWarningGetter (App.js:1053)
at Object.ReactElement.createElement (App.js:1220)
at Object.createElement (App.js:3329)
at Constructor.render (App.js:43403)
at App.js:15952
at measureLifeCyclePerf (App.js:15233)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (App.js:15951)
at ReactCompositeComponentWrapper._renderValidatedComponent (App.js:15978)
at ReactCompositeComponentWrapper._updateRenderedComponent (App.js:15902)
at ReactCompositeComponentWrapper._performComponentUpdate (App.js:15880)
何が問題なのかがわからない。ある関数を呼び出すと、それが別の関数を呼び出すというようなことなのかもしれないとは思っています。しかし、私のコードにはこのようなものは見当たりませんし、それがすべてなのかどうかもわかりません。助けてくれてありがとうございます :)
解決方法は?
問題は、あなたが
setState
をレンダー関数の内部から実行します。状態の変更は、ユーザーがボタンをクリックした、ブラウザ ウィンドウのサイズが変更された、写真が撮影されたなど、何かが変更された場合にのみ発生するはずです。
レンダリング中に状態を更新することは絶対にしないでください(この最後の文章を20回繰り返して、絶対に忘れないでください)。
以下は問題のコードです。
render () {
...
this.setState({
iconStyle: _props.iconStyle
});
this.setState({
style: _props.style
});
...
}
上記のコードでは、無限ループのようなものが発生します。
setState
は
render
が呼び出されます。このため
iconStyle
と
style
はプロップであり、プロップは変更できないので、これらのプロップを使用して初期状態を構築する必要があります。
getInitialState() {
return {
iconStyle: this.props.iconStyle,
style: this.props.style,
cursorPos: {},
};
}
その後、誰かがボタンをクリックして iconStyle を変更したい場合、状態を更新するクリックハンドラを作成します。
handleClick () {
this.setState({
iconStyle: 'clicked'
});
}
そうすると、コンポーネントが再レンダリングされ、新しい状態が反映されます。
誰かが料理をしていて、その様子を写真に撮ると考えてみてください。その 初期状態 は"卵を割ったものです。 いいえ , 小麦粉を注いだ。 いいえ , 野菜のみじん切り。 いいえ "、この状態を写真に撮るのです。すると、シェフが何かをする - 卵を割る。今度は状態が変わったので、それを写真に撮ります。次に、シェフが野菜を切ります。このときも、状態が変化しているので、写真を撮ります。
この例えの各写真は、あなたのレンダリング機能、つまりある時点の状態のスナップショットを表しています。もし、写真を撮るたびに小麦粉が降り注いだら、小麦粉が降り注いだばかりなので、また写真を撮らなければなりません。また写真を撮れば、さらに小麦粉が注がれるので、また写真を撮らなければなりません。結局、セリアックの悪夢でキッチンが天井までいっぱいになり、部屋にいる全員が窒息死することになる。フィルムやカメラのハードディスクの容量も足りなくなる。
関連
-
[解決済み】最大呼び出しスタックサイズ超過エラー
-
[解決済み】node.js TypeError: path must be absolute or specify root to res.sendFile [JSONのパースに失敗しました]。
-
[解決済み】Google Conversionsが動作しない - スクリプトが読み込まれない
-
[解決済み】BootstrapのCollapseが折りたたまれない
-
[解決済み】 Uncaught Error: Invariant Violation: 解決済み】 Uncaught Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function but got: object.
-
[解決済み】TypeError:res.jsonは関数ではありません。
-
[解決済み】ETIMEDOUTエラーの対処方法は?
-
[解決済み】「RangeError: 最大呼び出しスタックサイズを超えました」なぜ?
-
[解決済み] Chrome/jQuery Uncaught RangeError: 最大呼び出しスタックサイズを超えた
-
[解決済み] React - uncaught TypeError: 未定義のプロパティ 'setState' を読み取れない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Uncaught TypeError: 未定義のプロパティ 'top' を読み込めない
-
[解決済み】SecurityError: オリジンを持つフレームがクロスオリジンフレームにアクセスするのをブロックした
-
[解決済み】JavaScriptのinnerHTMLで要素が更新されない
-
[解決済み】「Uncaught TypeError: Chromeで "Illegal invocation "が発生する。
-
[解決済み】別のjsファイル内でJavaScriptの関数を呼び出す
-
[解決済み】ある要素を別の要素に移動させるには?
-
[解決済み】Uncaught ReferenceError。Reactが定義されていない
-
[解決済み】Javascript - ERR_CONTENT_LENGTH_MISMATCH
-
[解決済み】React-Routerの子が1つしかない。
-
[解決済み】リソースはドキュメントと解釈されるが、MIMEタイプはapplication/zipで転送される