ReactJS : setTimeout ()이 작동하지 않습니까?


102

이 코드를 염두에 두십시오.

var Component = React.createClass({

    getInitialState: function () {
        return {position: 0};    
    },

    componentDidMount: function () {
        setTimeout(this.setState({position: 1}), 3000);
    },

    render: function () {
         return (
            <div className="component">
                {this.state.position}
            </div>
         ); 
    }

});

ReactDOM.render(
    <Component />,
    document.getElementById('main')
);

상태는 3 초 후에 만 ​​변경되지 않습니까? 즉시 변경됩니다.

여기서 내 주요 목표는 3 초마다 상태를 변경하는 setInterval()것이지만 ( ) 작동하지 않았기 때문에 작동하지 않는을 시도했습니다 setTimeout(). 이것에 불이 있습니까? 감사!


2
당신이있는 경우 foo(bar())다음 bar되고 먼저 실행 및 반환 값이 전달됩니다 foo.
Felix Kling

@FelixKling은 정확하지만 적절하지 않습니다. foo()여기는 bar원하는 시간 초과 후에 정확히 실행 되기 때문 입니다. 아니면 내가 완전히 틀렸고 즉시 실행되고 원하는 시간 후에 만 ​​값을 반환합니까?
jbarradas

3
"여기서 foo ()는 정확히 원하는 시간 초과 후에 bar를 실행하기 때문입니다." 그렇기 때문에 bar호출하지 않고을 전달하고 반환 값을 전달해야합니다. 수행중인 작업 foo(bar())에 따라 의 동작이 변경 될 것으로 예상 했습니까 foo? 정말 이상 할 것입니다.
Felix Kling

답변:


245

하다

setTimeout(
    function() {
        this.setState({ position: 1 });
    }
    .bind(this),
    3000
);

그렇지 않으면, 당신은 결과 전달하는 setState로를 setTimeout.

ES6 화살표 기능을 사용하여 this키워드 사용을 피할 수도 있습니다 .

setTimeout(
  () => this.setState({ position: 1 }), 
  3000
);

1
네 말이되며 작동합니다. 그러나 function ()은 함수가 아닙니까? 그렇다면 왜 묶어야할까요? 나는 이미 시도했고 정말 필요했습니다. 이유를 알고 싶었습니다. : 당신의 도움에 대한 감사합니다
jbarradas

setTimeout에 결과를 전달한다고 말하는 이유를 모르겠습니다. 어떻게 작동하지 않습니까? 그 경우의 행동은 무엇입니까?
PositiveGuy

16
: 사용하는 것을 선호 분들을 위해 ES6 기능을 화살표 setTimeout(() => {this.setState({ position: 1 })}, 3000)당신이 당신 자신이 연구 한 경우 @PositiveGuy 확신이 질문에 게시하지 때문에,하지만 경우에 당신이하지 않은 : 다니엘의 원래의 예를 요구 .bind(this)제한 this에 컨텍스트를 setState- 그렇지 않으면 , this자동으로 호출되는 컨텍스트를 참조합니다 (이 경우 익명 function이에 전달됨 setTimeout). 그러나 ES6 화살표 함수는 어휘 적으로 범위가 지정this 되어 호출되는 컨텍스트로 제한 됩니다.
Zac Collier

1
작동하지 않습니다 ... setTimeout (() => {if (! this.props.logoIsLoading &&! this.props.isLoading) {console.log ( 'Will we appear?'); this.setState ({.. .this.state, shouldUpdate : false, itemToUpdate : null, modalIsOpen : false, modalTitle : '새 조직 추가'});}}, 100); 클래스 구문의 맥락에서 설탕 클래스 Organizations는 Component {console.log never gets console.log ( 'Will we would?'); 그 전후의 모든 것이 기록됩니다.
juslintek

@juslintek은 작동하지 않습니다. 필요한 경우 새로운 질문을하십시오.
다니엘 A. 화이트

150
setTimeout(() => {
  this.setState({ position: 1 });
}, 3000);

ES6 화살표 기능이의 컨텍스트를 변경하지 않기 때문에 위의 내용도 작동합니다 this.


3
ES6 구문은 React의 모범 사례에 대해 허용되는 답변이어야합니다. 둘 다 작동하지만 이것은 더 우아하고 처리합니다 this.
mccambridge

24

타임 아웃을 생성 할 때마다 componentWillUnmount에서이를 지워야합니다 (아직 실행되지 않은 경우).

      let myVar;
         const Component = React.createClass({

            getInitialState: function () {
                return {position: 0};    
            },

            componentDidMount: function () {
                 myVar = setTimeout(()=> this.setState({position: 1}), 3000)
            },

            componentWillUnmount: () => {
              clearTimeout(myVar);
             };
            render: function () {
                 return (
                    <div className="component">
                        {this.state.position}
                    </div>
                 ); 
            }

        });

ReactDOM.render(
    <Component />,
    document.getElementById('main')
);

11

이것이 조금 오래되었다는 것을 알고 있지만 React가 구성 요소가 마운트 해제 될 때 간격을 지우는 것이 좋습니다. https://reactjs.org/docs/state-and-lifecycle.html

그래서이 토론에이 답변을 추가하고 싶습니다.

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

8

setState괄호로 인해 즉시 호출됩니다! 익명 함수로 래핑 한 다음 호출합니다.

setTimeout(function() {
    this.setState({position: 1})
}.bind(this), 3000);

6

누가 setTimeout을 호출했는지 말하지 않았습니다.

여기서 추가 함수를 호출하지 않고 타임 아웃을 호출하는 방법입니다.

1. 추가 기능을 만들지 않고도 할 수 있습니다.

setTimeout(this.setState.bind(this, {position:1}), 3000);

용도의 function.prototype.bind ()

setTimeout은 함수의 위치를 ​​가져와 컨텍스트에 유지합니다.

2. 더 적은 코드를 작성하여도 동일한 작업을 수행하는 또 다른 방법입니다.

setTimeout(this.setState, 3000, {position:1});

아마도 어떤 시점에서 동일한 바인딩 방법을 사용합니다.

setTimeout은 함수의 위치 만 취하고 함수에 이미 컨텍스트가 있습니까? 어쨌든 작동합니다!

참고 : 이들은 js에서 사용하는 모든 기능에서 작동합니다.


5

코드 범위 ( this)window반응 구성 요소가 아닌 객체 가되므로 setTimeout(this.setState({position: 1}), 3000)이런 방식으로 충돌이 발생합니다.

즉하지 그것이, 반작용 자바 스크립트에서 오는 JS 폐쇄


따라서 현재 반응 구성 요소 범위를 바인딩하려면 다음을 수행하십시오.

setTimeout(function(){this.setState({position: 1})}.bind(this), 3000);

또는 브라우저가 es6를 지원하거나 projs가 es6를 es5로 컴파일하는 기능을 지원하는 경우 화살표 기능도 사용해보세요. 화살표 func는 '이'문제를 해결하는 것입니다.

setTimeout(()=>this.setState({position: 1}), 3000);

3

'setTimeout'함수 내에서 범위에 액세스하는 세 가지 방법이 있습니다.

먼저,

const self = this
setTimeout(function() {
  self.setState({position:1})
}, 3000)

두 번째는 ES6 화살표 함수를 사용하는 것입니다. 화살표 함수에는 자체 범위가 없었기 때문입니다 (this)

setTimeout(()=> {
   this.setState({position:1})
}, 3000)

세 번째는 함수 내부에 범위를 바인딩하는 것입니다.

setTimeout(function(){
   this.setState({position:1})
}.bind(this), 3000)

1

구문 선언 오류가 있습니다. 적절한 setTimeout 선언을 사용하십시오.

message:() => { 
  setTimeout(() => {this.setState({opened:false})},3000); 
  return 'Thanks for your time, have a nice day 😊! 
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.