简体   繁体   English

ReactJS与TypeScript无法呈现给DOM

[英]ReactJS with TypeScript not rendering to the DOM

I am working on a small project just to learn ReactJS and state and I am supposed to implement my own way of doing state. 我正在研究一个小项目,只是为了学习ReactJS和状态,我应该实现自己的状态。 I think I have it figured out but I cannot understand why this isn't working. 我想我已经想通了,但我无法理解为什么这不起作用。

I keep getting an error that says Cannot read property 'value' of null: 我一直收到一条错误,指出无法读取null的属性'value':

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import UsernameLogic  from './validation.ts';
import PasswordValidation from './passwordValidation.ts';

declare function require(prop: string): string;
require('./app.scss');

interface Props {

}

export default class App extends React.Component<Props, {}> {

    public criteria1 = {
        errorClass: 'errors',
        errorMessage: 'You must enter a Username!',
        isValid: false
    }

    public criteria2 = {
        errorClass: 'errors',
        errorMessage: 'Username must be at least 3 characters long',
        isValid: false
    }

    public criteria3 = {
        errorClass: 'approved',
        errorMessage: 'Username must not have numeric characters',
        isValid: true
    }

    public criteria4 = {
        errorClass: 'errors',
        errorMessage: 'Username must match existing User',
        isValid: false
    }

    public criteria5 = {
        errorClass: 'errors',
        errorMessage: 'You must enter a Password!',
        isValid: false
    }

    public criteron = [this.criteria1, this.criteria2, this.criteria3, this.criteria4, this.criteria5];





    render() {
        return (
            <form name="loginForm" className="loginForm">
                <div>
                    <div>
                        <input type="text" defaultValue="" placeholder="Username" id="usernameBox" className="inputField" onChange={UsernameLogic.validateUsername(this.criteron)}/>
                    </div>
                    <div>
                        <div id="R1" className={this.criteria1.errorClass}>{this.criteria1.errorMessage}</div>
                        <div id="R2" className={this.criteria2.errorClass}>{this.criteria2.errorMessage}</div>
                        <div id="R3" className={this.criteria3.errorClass}>{this.criteria3.errorMessage}</div>
                        <div id="R4" className={this.criteria4.errorClass}>{this.criteria4.errorMessage}</div>
                    </div>
                    <div>
                        <input type="password" defaultValue="" placeholder="Password" id="passwordBox" className="inputField" onChange={PasswordValidation.validatePassword(this.criteron)}/>
                    </div>
                    <div>
                        <div id="R5" className={this.criteria5.errorClass}>{this.criteria5.errorMessage}</div>
                    </div>
                </div>
                <input type="submit" />
            </form>
        );
    }
}



ReactDOM.render(<App />, document.getElementById("app") );

This is my logic: 这是我的逻辑:

export default class UsernameLogic {
    constructor(public validateUsername) {
        this.validateUsername = validateUsername;
    }

    public static validateUsername(currentState) {
        let V = ((<HTMLInputElement>document.getElementById("usernameBox")).value === null) ? '': ((<HTMLInputElement>document.getElementById("usernameBox")).value) ;

        if(currentState[0].isValid === false || 
           currentState[1].isValid === false ||
           currentState[2].isValid === false) {
        this.checkFirstCriteria(V, currentState);
        this.checkSecondCriteria(V, currentState);
        this.checkThirdCriteria(V, currentState);
           } else {
        this.checkFourthCriteria(V, currentState);
           }

    }

    static checkFirstCriteria(v, currentState) {
        if(v.length > 0) {
            let state: any;
            return (state = [ 
            {
                errorClass: 'approved',
                errorMessage: 'You must enter a Username!',
                isValid: true
            },
            ...currentState.slice(1,4)
            ]);
        }
        if(v.length === 0) {
            let state: any;
            return (state = [ 
            {
                errorClass: 'errors',
                errorMessage: 'You must enter a Username!',
                isValid: false
            },
            ...currentState.slice(1,4)
            ]);
        }
    }

    static checkSecondCriteria(v, currentState) {
        if(v.length >= 3) {
            let state: any;
            return( state = [
                ...currentState.slice(0,0),
                {
                    errorClass: 'approved',
                    errorMessage: 'Username must be at least 3 characters long',
                    isValid: true
                },
                ...currentState.slice(2,4)
            ]);
        }
        if(v.length < 3) {
            let state: any;
            return ( state = [
                ...currentState.slice(0,0),
                {
                    errorClass: 'errors',
                    errorMessage: 'Username must be at least 3 characters long',
                    isValid: false
                },
                ...currentState.slice(2,4)
            ]);
        }

    }


    static checkThirdCriteria(v, currentState) {
        if(v = /\[0-9]/) {
            let state: any;
            return ( state = [
                ...currentState.slice(0,1),
                {
                    errorClass: 'errors',
                    errorMessage: 'Username must not have numeric characters',
                    isValid: false
                },
                ...currentState.slice(3,4)
            ]);
        }
         if(v != /\[0-9]/) {
            let state: any;
            return ( state = [
                ...currentState.slice(0,1),
                {
                    errorClass: 'approved',
                    errorMessage: 'Username must not have numeric characters',
                    isValid: true
                },
                ...currentState.slice(3,4)
            ]);
        }
    }


    static checkFourthCriteria(v, currentState) {
        let availableUser = ['dustin','sule', 'lakshmi'];
        if(v === availableUser[0] || 
           v === availableUser[1] ||
           v === availableUser[2]) {
               let state: any;
               window.setTimeout(()=>{
                   return ( state = [
                       ...currentState.slice(0,2),
                       {
                           errorClass: 'approved',
                           errorMessage: 'Username must match existing User',
                           isValid: true
                       },
                       ...currentState.slice(4,4)
                   ]);
               }, 300)
           } else {
               let state: any;
               window.setTimeout(()=>{
                   return ( state = [
                       ...currentState.slice(0,2),
                       {
                           errorClass: 'errors',
                           errorMessage: 'Username must match existing User',
                           isValid: false
                       },
                       ...currentState.slice(4,4)
                   ]);
               }, 300)
           }

    }



}

So if anyone needs anymore information or can help me out that would be great. 因此,如果任何人需要更多的信息或可以帮助我,这将是伟大的。 It won't even render but its getting to my onChange event somehow. 它甚至不会呈现,但它以某种方式进入我的onChange事件。

That cast isn't in a .tsx file is it? 那个演员.tsx不在.tsx文件中呢? If your doing a cast like that inside TSX you have to do 如果你在TSX内做类似的演员,你必须这样做

document.getElementById("usernameBox") as HTMLInputElement

Also you could pass the event object to your validateUsername() function and get the value from that: 您还可以将事件对象传递给validateUsername()函数并从中获取值:

public static validateUsername(event, criterion) {
    let V = event.target.value;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM