[javascript] 반응 :“this”는 컴포넌트 함수 안에서 정의되지 않았다

class PlayerControls extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      loopActive: false,
      shuffleActive: false,
    }
  }

  render() {
    var shuffleClassName = this.state.toggleActive ? "player-control-icon active" : "player-control-icon"

    return (
      <div className="player-controls">
        <FontAwesome
          className="player-control-icon"
          name='refresh'
          onClick={this.onToggleLoop}
          spin={this.state.loopActive}
        />
        <FontAwesome
          className={shuffleClassName}
          name='random'
          onClick={this.onToggleShuffle}
        />
      </div>
    );
  }

  onToggleLoop(event) {
    // "this is undefined??" <--- here
    this.setState({loopActive: !this.state.loopActive})
    this.props.onToggleLoop()
  }

loopActive토글시 상태 를 업데이트하고 싶지만 this핸들러에서 객체가 정의되어 있지 않습니다. 튜토리얼 문서에 따르면 this구성 요소를 참조해야합니다. 뭔가 빠졌습니까?



답변

ES6 React.Component는 메소드를 자동 바인딩하지 않습니다. 생성자에서 직접 바인딩해야합니다. 이처럼 :

constructor (props){
  super(props);

  this.state = {
      loopActive: false,
      shuffleActive: false,
    };

  this.onToggleLoop = this.onToggleLoop.bind(this);

}


답변

몇 가지 방법이 있습니다.

하나는 this.onToggleLoop = this.onToggleLoop.bind(this);생성자 를 추가
하는 것입니다.

또 다른 하나는 화살표 기능
onToggleLoop = (event) => {...}입니다.

그리고있다 onClick={this.onToggleLoop.bind(this)}.


답변

이 방법으로 함수를 작성하십시오.

onToggleLoop = (event) => {
    this.setState({loopActive: !this.state.loopActive})
    this.props.onToggleLoop()
}

팻 화살표 기능

키워드의 바인딩은 지방 화살표 함수의 외부와 내부에서 동일합니다. 이것은 함수로 선언 된 함수와 다르며 호출시 이것을 다른 객체에 바인딩 할 수 있습니다. 이 바인딩을 유지하는 것은 매핑과 같은 작업에 매우 편리합니다 : this.items.map (x => this.doSomethingWith (x)).


답변

렌더링 함수에서 비슷한 바인딩을 실행 this하여 다음과 같은 방식으로 컨텍스트를 전달했습니다 .

{someList.map(function(listItem) {
  // your code
}, this)}

나는 또한 사용했다 :

{someList.map((listItem, index) =>
    <div onClick={this.someFunction.bind(this, listItem)} />
)}


답변

당신은 그주의해야 this객체의 메서드가 그 같이 함수를 호출 할 때 : 기능은 예를 호출하는 방법에 따라 달라 this메소드가 호출 된 객체로 설정됩니다.

thisJSX 컨텍스트에서 컴포넌트 객체로 액세스 할 수 있으므로 원하는 메소드를 메소드로 인라인으로 호출 할 수 있습니다 this.

함수 / 메소드에 대한 참조를 전달하면 반응이 독립적 인 함수로 호출하는 것처럼 보입니다.

onClick={this.onToggleLoop} // Here you just passing reference, React will invoke it as independent function and this will be undefined

onClick={()=>this.onToggleLoop()} // Here you invoking your desired function as method of this, and this in that function will be set to object from that function is called ie: your component object


답변

babel을 사용하는 경우 ES7 바인드 연산자 https://babeljs.io/docs/en/babel-plugin-transform-function-bind#auto-self-binding을 사용하여 ‘this’를 바인딩합니다.

export default class SignupPage extends React.Component {
  constructor(props) {
    super(props);
  }

  handleSubmit(e) {
    e.preventDefault();

    const data = {
      email: this.refs.email.value,
    }
  }

  render() {

    const {errors} = this.props;

    return (
      <div className="view-container registrations new">
        <main>
          <form id="sign_up_form" onSubmit={::this.handleSubmit}>
            <div className="field">
              <input ref="email" id="user_email" type="email" placeholder="Email"  />
            </div>
            <div className="field">
              <input ref="password" id="user_password" type="new-password" placeholder="Password"  />
            </div>
            <button type="submit">Sign up</button>
          </form>
        </main>
      </div>
    )
  }

}


답변

componentDidMount …와 같은 라이프 사이클 메소드에서 작성된 메소드 를 호출 하면 this.onToggleLoop = this.onToogleLoop.bind(this)및 fat 화살표 함수 만 사용할 수 있습니다 onToggleLoop = (event) => {...}.

수명주기 메소드가 더 일찍 호출되므로 생성자에서 함수 선언에 대한 일반적인 접근 방식이 작동하지 않습니다.