【问题标题】:'this' keyword is undefined inside Mapping Statement (React)'this' 关键字在映射语句 (React) 中未定义
【发布时间】:2020-03-31 04:02:50
【问题描述】:

vidsAsHtml 映射函数中的 this 关键字一直返回 undefined。

我阅读了this,以及其他几个关于此的 SO 问题,但他们的解决方案并没有解决问题。我已经为地图使用了 es6 语法箭头函数,但我也尝试将其作为第二个参数,但这并没有解决问题。好奇是否有人知道为什么“this”关键字在这里一直出现未定义。

 import React, { useState, useEffect } from 'react'
    import axios from 'axios'

    const VideoGrid = (props) => {
      const [videos, setResource] = useState([])

      const fetchVideos = async (amount, category) => {
        const response = await axios.get('https://pixabay.com/api/videos/', {
          params: {
            key: '123456679',
            per_page: amount,
            category: category
          }
        })

        console.log(response)
        const vidsAsHtml = response.data.hits.map(vid => {
          return (
            <div className={`${props.page}--grid-content-wrapper`} key={vid.picture_id}>
              <div className={`${props.page}--grid-video`}>
                <video
                  poster="https://i.imgur.com/Us5ckqm.jpg"
                  onMouseOver={this.play()}
                  onMouseOut={this.pause()}
                  src={`${vid.videos.tiny.url}#t=1`} >
                </video>
              </div>
              <div className={`${props.page}--grid-avatar-placeholder`}></div>
              <div className={`${props.page}--grid-title`}>{vid.tags}</div>
              <div className={`${props.page}--grid-author`}>{vid.user}</div>
              <div className={`${props.page}--grid-views`}>{vid.views} 
                <span className={`${props.page}--grid-date`}> • 6 days ago</span>
              </div>
            </div>
          )
      })
      setResource(vidsAsHtml)
    }

      useEffect(() => {
        fetchVideos(50, 'people')
      }, []) 

        return (
          <main className={`${props.page}--grid-background`}>
            <nav className={`${props.page}--grid-nav`}>

              <button 
                id='followButton' 
                className={`${props.page}--grid-nav-${props.titleOne}`} 
                >{props.titleOne}
              </button>

              <button 
                id='recommendedButton' 
                className={`${props.page}--grid-nav-${props.titleTwo}`} 
                >{props.titleTwo}
              </button>

              <button 
                id='subscriptionsButton' 
                className={`${props.page}--grid-nav-${props.titleThree}`} 
                >{props.titleThree}
              </button>

              <button className={`${props.page}--grid-nav-${props.titleFour}`}>{props.titleFour}</button>
              <button className={`${props.page}--grid-nav-${props.titleFive}`}>{props.titleFive}</button>
              <button className={`${props.page}--grid-nav-follow`}>FOLLOW</button>
            </nav>
            <hr className={`${props.page}--grid-hr-nav-grey`} />
            <hr className={`${props.page}--grid-hr-nav-black`} />        

            <div className={`${props.page}--grid`} style={{marginTop: 'unset'}}>
              {videos}
            </div>
          </main>
        )
      }


    export default VideoGrid

【问题讨论】:

  • 功能组件无权访问this。试试这个onMouseOver={play()}
  • 这给了我 play() 和 pause() 没有定义

标签: reactjs ecmascript-6 promise this react-hooks


【解决方案1】:

事件处理程序道具应该被传递给一个函数。目前您正在尝试将this.play()this.pause() 的返回值作为事件处理程序传递,这无论如何都不起作用。

React 也不会通过this 使事件处理程序可以使用该元素,但您可以通过event.target 访问它:

<video
  poster="https://i.imgur.com/Us5ckqm.jpg"
  onMouseOver={event => event.target.play()}
  onMouseOut={event => event.target.pause()}
  src={`${vid.videos.tiny.url}#t=1`} >
</video>

【讨论】:

  • Ughhhh...我花了几个小时弄乱 ref 系统,在外部函数中尝试 querySelectors 以及其他一些东西,尽管我从一开始就觉得我需要使用这样的事件.只是不知道使事件正常工作所需的确切语法,而且我查看的其他 SO 问题都没有使用它。该死的......好吧,它就像一场梦一样。谢谢。
【解决方案2】:

您可以为此使用ref

let vidRef = React.createRef();

你应该单独创建函数,

const playVideo = () => {
   // You can use the play method as normal on your video ref
    vidRef.current.play();
};

const pauseVideo = () => {
   // Pause as well
   vidRef.current.pause();
};

提供参考video

<video
  ref = {vidRef}   //Provide ref here
  poster="https://i.imgur.com/Us5ckqm.jpg"
  onMouseOver={() => playVideo()}
  onMouseOut={() => pauseVideo()}
  src={`${vid.videos.tiny.url}#t=1`} >
</video>

Demo

【讨论】:

  • 给我 vidRef.play() 不是函数
  • 尝试打印vidRef,看看它是否引用了正确的元素。另外,试试vidRef.current.play()
  • vidRef 会在 DOM 加载时立即在每个视频的控制台中运行,其值为 undefined。第二个选项给出了无法读取未定义的属性播放。
  • 在未定义的控制台日志下,它给出了错误:未捕获的不变违规:元素引用被指定为字符串 (vidRef),但没有设置所有者。
  • 我刚刚尝试了您的更新解决方案。现在 console.log(vidRef) 在鼠标悬停时给了我视频对象。现在的问题是当我鼠标悬停时只有声音开始播放,而不是视频。我使用的视频与您在演示中使用的视频相同。
猜你喜欢
  • 2020-05-04
  • 2023-01-14
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 2022-12-17
相关资源
最近更新 更多