Javascript 为什么我会得到;在嵌套函数中通过此函数对类字段的引用访问可能无效;错误

Javascript 为什么我会得到;在嵌套函数中通过此函数对类字段的引用访问可能无效;错误,javascript,reactjs,debugging,Javascript,Reactjs,Debugging,在vanilla JS中,我的代码可以正常工作。在这种情况下,我想对我的Wall类进行组件化,它应该在浏览器中显示用户上传的图像。同样,这在vanilla JS中正常工作,但在JSX中不正常 我在document.querySelector(“#file input”).addEventListener(“change”,this.previewImages)上的嵌套函数中获得了对类字段的潜在无效引用访问权行,我认为这是导致问题的原因 我做错了什么?我该如何修复它 import React, {

在vanilla JS中,我的代码可以正常工作。在这种情况下,我想对我的
Wall
类进行组件化,它应该在浏览器中显示用户上传的图像。同样,这在vanilla JS中正常工作,但在JSX中不正常

我在
document.querySelector(“#file input”).addEventListener(“change”,this.previewImages)上的嵌套函数
中获得了对类字段的
潜在无效引用访问权行,我认为这是导致问题的原因

我做错了什么?我该如何修复它

import React, {Component} from 'react';

class Wall extends Component {
    constructor(props) {
        super(props);
        this.previewImages = this.previewImages.bind(this);
    }

    previewImages() {
        let preview = document.createElement("div");

        if (this.files) {
            [].forEach().call(this.files, readAndPreview());
        }

        function readAndPreview() {
            if (!/\.(jpe?g|png|gif)$/i.test(file.name)) {
                return alert(file.name + " is not an image");
            }

            let reader = new FileReader();

            reader.addEventListener("load", () => {
                let image = new Image();
                image.height = 100;
                image.title = file.name;
                image.src = this.result;

                let date = Date.now();
                let d = new Date(parseInt(date, 10));
                let ds = d.toString("MM/dd/yy HH:mm:ss");
                console.log(ds);

                let initialCountOfLikes = 0;
                let zeroLikes = document.createElement("h1");
                let zeroLikesTextNode = zeroLikes.createTextNode(initialCountOfLikes + " likes");

                zeroLikes.appendChild(zeroLikesTextNode);

                preview.appendChild(image); // makes image appear
                preview.appendChild(zeroLikes); // makes like count appear

                image.ondblclick = function() {
                    if (initialCountOfLikes === 0) {
                        console.log("Inside if block");
                        initialCountOfLikes++;
                        console.log("initialCountOfLikes++ => " + initialCountOfLikes);
                    } else if (initialCountOfLikes === 1) {
                        console.log("inside second else if block");
                        initialCountOfLikes--;
                        console.log("initialCountOfLikes-- => " + initialCountOfLikes);
                    }
                    zeroLikesTextNode.nodeValue = initialCountOfLikes + " likes";
                };
            });
            reader.readAsDataURL(file);
            document.querySelector("#file-input").addEventListener("change", this.previewImages);
        }
    }

    render() {
        return (
            <div id="file-input-wrapper">
                <input type="file" />
                <label htmlFor="file-input" id={"LblBrowse"} />
            </div>
        );
    }
}

export default Wall;
import React,{Component}来自'React';
类墙扩展组件{
建造师(道具){
超级(道具);
this.previewImages=this.previewImages.bind(this);
}
预览图像(){
让preview=document.createElement(“div”);
if(this.files){
[].forEach().call(this.files,readAndPreview());
}
函数readAndPreview(){
if(!/\(jpe?g | png | gif)$/i.test(file.name)){
返回警报(file.name+“不是图像”);
}
let reader=new FileReader();
reader.addEventListener(“加载”,()=>{
让图像=新图像();
image.height=100;
image.title=file.name;
image.src=this.result;
让date=date.now();
设d=新日期(parseInt(日期,10));
设ds=d.toString(“MM/dd/yy HH:MM:ss”);
控制台日志(ds);
让initialCountOfLikes=0;
设zeroLikes=document.createElement(“h1”);
让zeroLikesTextNode=zeroLikes.createTextNode(initialCountOfLikes+“likes”);
appendChild(zeroLikesTextNode);
preview.appendChild(图像);//使图像显示
preview.appendChild(zeroLikes);//显示like计数
image.ondblclick=函数(){
if(initialCountOfLikes==0){
控制台日志(“内部if块”);
initialCountOfLikes++;
log(“initialCountOfLikes++=>”+initialCountOfLikes);
}else if(initialCountOfLikes==1){
console.log(“在第二个else块内”);
初始的生命数--;
log(“initialCountOfLikes-->”+initialCountOfLikes);
}
zeroLikesTextNode.nodeValue=initialCountOfLikes+“likes”;
};
});
reader.readAsDataURL(文件);
document.querySelector(“文件输入”).addEventListener(“更改”,this.previewImages);
}
}
render(){
返回(
);
}
}
导出默认墙;

警告告诉您,在JavaScript中使用
这个
经常会产生混淆的含义,特别是在嵌套在另一个函数中的函数中使用时
停止引用类,而是引用嵌套函数的范围

在您的例子中,这可能是一个合理的问题(我认为),因为您有一个类,
Wall
,它有一个方法
previewImages()
和一个属性
files
。在该函数中,您实例化了一个新函数,
readAndPreview()
,在其中指定
this.previewImages
作为对
addEventListener
函数的函数回调

他们说您可能错误地使用了
this.previewImages
,因为您使用传统JavaScript语法编写函数,
function foo(){…}
,其中
this
在每个子函数调用中不断被重新定义。在您的情况下,我相信
引用的是
readAndPreview()
的上下文,因此无法访问方法
this.previewImages()
,因为
未引用父类
Wall

人们过去常做这样的事情,比如,做一个
var=this,您会知道,
总是指父类

但是现在,使用使用“胖箭头”语法的ES6 lambda函数
()=>{}
您可以访问
,并知道它引用的是父范围

我相信您可以重构类,将
previewImages(){
更改为
previewImages=()=>{
,并且知道
将引用该类。您必须对
函数readAndPreview(){
执行相同操作。将其更改为
const readAndPreview=()=>{
。但是,如果要将其设置为变量,我认为您必须将其移动到您调用它的位置上方。例如,上面

if (this.files) {
    [].forEach().call(this.files, readAndPreview());
}

我在第八章中遇到了这个错误。 我用箭头函数代替常规函数来求解

就你而言

        readAndPreview = () => { ... }

这可能会解决你的问题。

哪一行抛出错误,确切地说?考虑删除不必要的代码。看这是一个独立的组件吗?我找不到任何带有ID“代码>文件输入< /代码>的元素。要与dom通信,我认为它的
ref
,您可能应该避免直接使用
querySelector