React: “this” is undefined inside a component function

前端 未结 10 2113
春和景丽
春和景丽 2020-11-22 04:59
class PlayerControls extends React.Component {
  constructor(props) {
    super(props)

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


        
相关标签:
10条回答
  • 2020-11-22 05:34

    I ran into a similar bind in a render function and ended up passing the context of this in the following way:

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

    I've also used:

    {someList.map((listItem, index) =>
        <div onClick={this.someFunction.bind(this, listItem)} />
    )}
    
    0 讨论(0)
  • 2020-11-22 05:35

    ES6 React.Component doesn't auto bind methods to itself. You need to bind them yourself in constructor. Like this:

    constructor (props){
      super(props);
      
      this.state = {
          loopActive: false,
          shuffleActive: false,
        };
      
      this.onToggleLoop = this.onToggleLoop.bind(this);
    
    }
    
    0 讨论(0)
  • 2020-11-22 05:35

    If you call your created method in the lifecycle methods like componentDidMount... then you can only use the this.onToggleLoop = this.onToogleLoop.bind(this) and the fat arrow function onToggleLoop = (event) => {...}.

    The normal approach of the declaration of a function in the constructor wont work because the lifecycle methods are called earlier.

    0 讨论(0)
  • 2020-11-22 05:39

    In my case, for a stateless component that received the ref with forwardRef, I had to do what it is said here https://itnext.io/reusing-the-ref-from-forwardref-with-react-hooks-4ce9df693dd

    From this (onClick doesn't have access to the equivalent of 'this')

    const Com = forwardRef((props, ref) => {
      return <input ref={ref} onClick={() => {console.log(ref.current} } />
    })
    

    To this (it works)

    const useCombinedRefs = (...refs) => {
      const targetRef = React.useRef()
    
      useEffect(() => {
        refs.forEach(ref => {
          if (!ref) return
    
          if (typeof ref === 'function') ref(targetRef.current)
          else ref.current = targetRef.current
        })
      }, [refs])
    
      return targetRef
    }
    
    const Com = forwardRef((props, ref) => {
      const innerRef = useRef()
      const combinedRef = useCombinedRefs(ref, innerRef)
    
      return <input ref={combinedRef } onClick={() => {console.log(combinedRef .current} } />
    })
    
    0 讨论(0)
  • 2020-11-22 05:41

    Write your function this way:

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

    Fat Arrow Functions

    the binding for the keyword this is the same outside and inside the fat arrow function. This is different than functions declared with function, which can bind this to another object upon invocation. Maintaining the this binding is very convenient for operations like mapping: this.items.map(x => this.doSomethingWith(x)).

    0 讨论(0)
  • 2020-11-22 05:47

    There are a couple of ways.

    One is to add this.onToggleLoop = this.onToggleLoop.bind(this); in the constructor.

    Another is arrow functions onToggleLoop = (event) => {...}.

    And then there is onClick={this.onToggleLoop.bind(this)}.

    0 讨论(0)
提交回复
热议问题