反应上下文-“ this”未定义

时间:2020-03-19 18:28:23

标签: javascript reactjs react-context

我正在使用React Context来管理全局状态。

因此,我已使用提供者和使用者定义了上下文。

我有我的videoplaying-context.js

import React from "react";
import { createContext } from 'react';

// set the defaults
const VideoContext = React.createContext({
  videoPlaying: false,
  setPlayingVideo: () => {}
});

export default VideoContext;

在我的_app.js中,我有:

import App from 'next/app'
import { PageTransition } from 'next-page-transitions'
import VideoContext from '../components/videoplaying-context'

class MyApp extends App {
  setPlayingVideo = videoPlaying => {
    this.setState({ videoPlaying });
  };

  state = {
    videoPlaying: false,
    setPlayingVideo: this.setPlayingVideo
  }
  render() {
    console.log('new _app.js defalt page');
    const { Component, pageProps, router, state } = this.props
    return (
      <React.Fragment>
        <VideoContext.Provider value={this.state}>
          <PageTransition timeout={300} classNames="page-transition">
            <Component {...pageProps} key={router.route} />
          </PageTransition>
        </VideoContext.Provider>
      </React.Fragment>
    )
  }
}

export default MyApp

然后在我的文件之一中放入了Consumer:

import Layout from "../components/Layout";
import ReactPlayer from 'react-player
import VideoContext from '../components/videoplaying-context'

class Video extends React.Component {
  constructor(props) {
    super(props);
    this.triggerVideo = this.triggerVideo.bind(this);
  }
  triggerVideo(event) {
    console.log("click");
    /* doing other stuff here... */
  }
  render() {
    return (
      <VideoContext.Consumer>
        {context => (
          <Layout>
            <h1>Videos</h1>
            <div>
              <div className="group" id="process-video">
                <div
                  className="poster-image"
                  onClick={() => {
                    this.triggerVideo.bind(this);
                    context.setPlayingVideo(true);
                  }}
                />
                <ReactPlayer
                  url="https://vimeo.com/169599296"
                  width="640px"
                  height="640px"
                  config={{
                    vimeo: {
                      playerOptions: {
                        thumbnail_url: "http://placehold.it/640x640.jpg",
                        thumbnail_width: 640,
                        thumbnail_height: 640
                      }
                    }
                  }}
                />
              </div>
            </div>
            <style jsx global>{`
              .group {
                position: relative;
                height: 0;
                overflow: hidden;
                height: 640px;
                width: 640px;
              }

              .poster-image {
                background: url("http://placehold.it/640x640.jpg") center center;
                background-size: cover;
                bottom: 0;
                left: 0;
                opacity: 1;
                position: absolute;
                right: 0;
                top: 0;
                z-index: 10;
                height: 640px;
                width: 640px;
                transition: all 0.4s ease-in;
              }

              .poster-image + div {
                position: absolute;
                top: 0;
                left: 0;
                width: 640px;
                height: 640px;
              }

              .poster-image.video--fadeout {
                opacity: 0;
              }
            `}</style>
          </Layout>
        )}
      </VideoContext.Consumer>
    );
  }
}

export default Video;

因此,函数“ context.setPlayingVideo(true)”可以正常工作,并且可以将全局状态“ videoPlaying”正确设置为true,但是在引入上下文后,“ this.triggerVideo.bind(this); ”不再起作用,因为“ this”未定义。

我尝试删除它和其他内容,但是我真的卡住了,不知道要修复它。

谢谢大家!

1 个答案:

答案 0 :(得分:2)

在这一行上,您没有调用方法triggerVideo

onClick={() => { this.triggerVideo.bind(this); context.setPlayingVideo(true); }}

更改为:

onClick={() => { this.triggerVideo(); context.setPlayingVideo(true); }}

或:

onClick={() => { this.triggerVideo.bind(this)(); context.setPlayingVideo(true); }}