setState (…) : 마운트되거나 마운트 된 구성 요소 만 업데이트 할 수 있습니다. 이것은 일반적으로 마운트되지 않은 구성 요소에서 setState ()를 호출했음을 의미합니다. 이것은 작동하지 않습니다
componentDidMount(prevProps, prevState, prevContext) {
let [audioNode, songLen] = [this.refs.audio, List.length-1];
audioNode.addEventListener('ended', () => {
this._endedPlay(songLen, () => {
this._currSong(this.state.songIndex);
this._Play(audioNode);
});
});
audioNode.addEventListener('timeupdate', () => {
let [remainTime, remainTimeMin, remainTimeSec, remainTimeInfo] = [];
if(!isNaN(audioNode.duration)) {
remainTime = audioNode.duration - audioNode.currentTime;
remainTimeMin = parseInt(remainTime/60); // 剩余分
remainTimeSec = parseInt(remainTime%60); // 剩余秒
if(remainTimeSec < 10) {
remainTimeSec = '0'+remainTimeSec;
}
remainTimeInfo = remainTimeMin + ':' + remainTimeSec;
this.setState({'time': remainTimeInfo});
}
});
}
componentWillUnmount () {
let audio = this.refs.audio;
audio.removeEventListener('timeupdate');
audio.removeEventListener('ended');
}
오류:
경고 : setState (...) : 마운트되었거나 마운트 된 구성 요소 만 업데이트 할 수 있습니다. 이것은 일반적으로 마운트되지 않은 구성 요소에서 setState ()를 호출했음을 의미합니다. 이건 안돼. 정의되지 않은 구성 요소에 대한 코드를 확인하십시오.
에서 '종료 된'EventListener를 제거 componentWillUnmount
했지만 작동하지 않습니다. 나는 추가하기 때문에 this.setState({'time': remainTimeInfo});
에서 componentDidMount
.
구성 요소에 참조 를 할당 한 다음 상태를 설정하기 전에 참조가 있는지 확인 하여이 문제를 해결했습니다 .
myMethod(){
if (this.refs.myRef)
this.setState({myVar: true});
}
render() {
return (
<div ref="myRef">
{this.state.myVar}
</div>
);
}
removeEventListener
와 동일한 서명이 있습니다 addEventListener
. 리스너를 제거하려면 모든 인수가 정확히 동일해야합니다.
var onEnded = () => {};
audioNode.addEventListener('ended', onEnded, false);
this.cleanup = () => {
audioNode.removeEventListener('ended', onEnded, false);
}
그리고 componentWillUnmount 호출에서 this.cleanup()
.
생성자 setState
대신 사용했기 때문에이 문제가 발생했습니다 state
.
예
다음 잘못된 코드 변경
constructor(props) {
super(props);
this.setState({
key: ''
});
}
...에
constructor(props) {
super(props);
this.state = {
key: ''
};
}
Edit : isMounted
더 이상 사용되지 않으며 React의 이후 버전에서 제거 될 것입니다. 참조 이 이를 isMounted는 안티 패턴입니다 .
경고 상태로, 당신은 호출 this.setState
하는 A 구성 요소에 있었다 장착하지만 그 이후 마운트 해제되었습니다.
코드가 안전한지 확인하려면 코드를
if (this.isMounted()) {
this.setState({'time': remainTimeInfo});
}
구성 요소가 여전히 마운트되었는지 확인합니다.
최신 반응 버전을 업데이트 한 이후 동일한 문제에 직면했습니다. 아래와 같이 해결됩니다.
내 코드는
async componentDidMount() {
const { default: Component } = await importComponent();
Nprogress.done();
this.setState({
component: <Component {...this.props} />
});
}
로 변경
componentWillUnmount() {
this.mounted = false;
}
async componentDidMount() {
this.mounted = true;
const { default: Component } = await importComponent();
if (this.mounted) {
this.setState({
component: <Component {...this.props} />
});
}
}
나는 전에이 문제가 있었고 React 공식 페이지 isMounted is an Antipattern 에 따라 해결했습니다 .
에서 속성 isMounted
플래그를 true로 설정하고 에서 componentDidMount
false로 전환합니다 componentWillUnmount
. setState()
콜백 할 때 isMounted
먼저 확인하십시오 ! 그것은 나를 위해 작동합니다.
state = {
isMounted: false
}
componentDidMount() {
this.setState({isMounted: true})
}
componentWillUnmount(){
this.setState({isMounted: false})
}
콜백 :
if (this.state.isMounted) {
this.setState({'time': remainTimeInfo});}
이 스레드의 많은 답변은 refs를 사용하는 요점을 얻었지만 완전한 예제가 좋을 것이라고 생각합니다. 이벤트 리스너를 사용하고 React 컨텍스트를 벗어나 실제 DOM 노드에서 작동하므로 ref는 표준 솔루션으로 간주되어야합니다. 다음은 완전한 예입니다.
class someComponent extends Component {
constructor(props) {
super(props)
this.node = null
}
render() {
return (
<div ref={node => { this.node = node }}>Content</div>
)
}
handleEvent(event) {
if (this.node) {
this.setState({...})
}
}
componentDidMount() {
//as soon as render completes, the node will be registered.
const handleEvent = this.handleEvent.bind(this)
this.node.addEventListener('click', handleEvent)
}
componentWillUnmount() {
const handleEvent = this.handleEvent.bind(this)
this.node.removeEventListener('click', handleEvent)
}
}
addEventListener 및 removeEventListener , 콜백은 익명 내부 클래스가 아니어야하며 동일한 매개 변수를 가져야합니다.
Ajax 요청의 성공 / 실패 콜백에 대한 팝업 (부트 스트랩 모달)을 표시하려고 할 때이 경고가 표시되었습니다. 또한 setState가 작동하지 않고 팝업 모달이 표시되지 않았습니다.
아래는 내 상황-
<Component /> (Containing my Ajax function)
<ChildComponent />
<GrandChildComponent /> (Containing my PopupModal, onSuccess callback)
I was calling ajax function of component from grandchild component passing a onSuccess Callback (defined in grandchild component) which was setting state to show popup modal.
I changed it to -
<Component /> (Containing my Ajax function, PopupModal)
<ChildComponent />
<GrandChildComponent />
Instead I called setState (onSuccess Callback) to show popup modal in component (ajax callback) itself and problem solved.
In 2nd case: component was being rendered twice (I had included bundle.js two times in html).
Having named method in place of the anonymous function in audioNode.addEventListener
's callback should eliminate the subject warning:
componentDidMount(prevProps, prevState, prevContext) {
let [audioNode, songLen] = [this.refs.audio, List.length-1];
audioNode.addEventListener('ended', () => {
this._endedPlay(songLen, () => {
this._currSong(this.state.songIndex);
this._Play(audioNode);
});
});
audioNode.addEventListener('timeupdate', this.callbackMethod );
}
callBackMethod = () => {
let [remainTime, remainTimeMin, remainTimeSec, remainTimeInfo] = [];
if(!isNaN(audioNode.duration)) {
remainTime = audioNode.duration - audioNode.currentTime;
remainTimeMin = parseInt(remainTime/60); // 剩余分
remainTimeSec = parseInt(remainTime%60); // 剩余秒
if(remainTimeSec < 10) {
remainTimeSec = '0'+remainTimeSec;
}
remainTimeInfo = remainTimeMin + ':' + remainTimeSec;
this.setState({'time': remainTimeInfo});
}
}
And yes, named method is needed anyways because removeEventListener
won't work with anonymous callbacks, as mentioned above several times.
- Cancel all async operation in
componentWillUnmount
- Check component is already unmounted when async call
setState
,
since isMounted flag is deprecated
'Development Tip' 카테고리의 다른 글
임의의 문자열과 임의의 16 진수를 만드는 가장 간단한 방법 (0) | 2020.10.17 |
---|---|
파이썬에서 날짜에서 한 달을 빼는 가장 간단한 방법은 무엇입니까? (0) | 2020.10.17 |
로드는 Ruby의 require와 어떻게 다릅니 까? (0) | 2020.10.16 |
Html.BeginForm ()으로 폼의 이름을 어떻게 지정할 수 있습니까? (0) | 2020.10.16 |
VS2010은 Windows 64 비트 버전의 WinForms 응용 프로그램에서 처리되지 않은 예외 메시지를 표시하지 않습니다. (0) | 2020.10.16 |