反应&打字稿:无法读取属性' 0'未定义的

时间:2017-12-20 19:01:36

标签: javascript reactjs typescript

我最近从.jsx转到了.tsx,我遇到了问题(在转到打字稿之前,一切运作良好)。第一个错误是在行:&#34; <Modal show={this.state.isOpen[key]} onClose={this.handleToggleModal.bind(__this,key)}>&#34;。我怀疑那里有与打字稿相关的东西,但我不知道是什么。有人可以帮帮我吗?

// TaskCard.tsx

//Dependencies
import * as React from 'react';

//Copmponents
import Modal, {ModalProps} from './Modal';
import Input from './Input';
import {IBoard} from './Board';
import PostComment from './PostComment';

export interface IComments{
    body: string,
    from: string,
    date: string,
    hour: string
}

export interface ITask{
    board: string,
    duedate: string,
    tag: string,
    tagClass: string,
    tagText: string,
    body: string,
    risk: string,
    responsable: string
    comments: IComments[]
}

export interface TaskProps{
    tasks: ITask[]
    boards: IBoard[]
}

export interface TaskState{
    isOpen: {}
}

class TaskCard extends React.Component<TaskProps, TaskState>{
    constructor(props) {
        super(props);

        this.state = { 
            isOpen: props.isOpen
        };
    }

    handleToggleModal(key) {
        this.state.isOpen[key] = !this.state.isOpen[key];
        this.setState(this.state.isOpen);
    }

    render(){
        const { tasks, boards } = this.props;
        let __this = this;

        return(
            tasks && tasks.map(
                (tasks, key) =>
                <div key={key} className="v-margin no-margin-top card-contour medium" onClick={this.handleToggleModal.bind(__this,key)}>
                    <div className="row middle-xs caption">
                        <div className="col-xs-6 no-padding">
                            <div className="row middle-xs">
                                <img className="img_icn no-padding-left" src="./assets/img/icn_calendar.svg" alt=""/>
                                <p className="txt-tertiary-color">{tasks.duedate}</p>
                            </div>
                        </div>
                        <div className="col-xs-6 no-padding">
                            <div className="row end-xs middle-xs">
                                <div className={tasks.tagClass + " tag tag_box center-align"}>
                                    <p>{tasks.tag}</p>
                                    <span className="tag_hint">{tasks.tagText}</span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="row middle-row v-padding">
                        <p>{tasks.body}</p>
                    </div>
                    <div className="row middle-xs caption">
                        <div className="col-xs-9 no-padding">
                            <div className="row middle-xs">
                                <img className="img_icn no-padding-left" src="./assets/img/icn_target.svg" alt=""/>
                                <p className="txt-tertiary-color">Riesgos: {tasks.risk}%</p>
                            </div>
                        </div>
                        <div className="col-xs-3 no-padding">
                            <div className="row middle-xs end-xs">
                                <img className="img_icn no-padding-left" src="./assets/img/icn_comments.svg" alt=""/>
                                <p className="txt-tertiary-color">{tasks.comments.length}</p>
                            </div>
                        </div>
                    </div>
                    <Modal show={this.state.isOpen[key]} onClose={this.handleToggleModal.bind(__this,key)}>
                        <div className="modal_container">
                            <section className="modal_section">
                                <div className="row middle-xs no-margin-left no-margin-right modal_section_title">
                                    <object width="20px" height="20px" data="./assets/img/icn_objetive-blue.svg"></object>
                                    <div className="col-xs start-xs">
                                        <h4 className="semi-bold">Objetivo</h4>
                                    </div>
                                </div>
                                <div className="col-xs-12 modal_section_content">
                                    <p>{tasks.body}</p>
                                </div>
                            </section>
                            <section className="modal_section">
                                <div className="row middle-xs no-margin-left no-margin-right modal_section_title">
                                    <object width="20px" height="20px" data="./assets/img/icn_target-blue.svg"></object>
                                    <div className="col-xs start-xs">
                                        <h4 className="semi-bold">Target</h4>
                                    </div>
                                </div>
                                <div className="col-xs-12 modal_section_content">
                                    <p>Riesgos / Problemas = {tasks.risk}%</p>
                                    <div className="table v-margin">
                                        <div className="row middle-xs">
                                            <div className="col-xs">
                                                <p className="table_head">Fecha de vencimiento</p>
                                                <p className="table_body">{tasks.duedate}</p>
                                            </div>
                                            <div className="col-xs">
                                                <p className="table_head">Tipo de objetivo</p>
                                                <p className="table_body">{tasks.tagText}</p>
                                            </div>
                                            <div className="col-xs">
                                                <p className="table_head">Responsable</p>
                                                <p className="table_body">{tasks.responsable}</p>
                                            </div>
                                            <div className="col-xs-12 v-margin no-margin-bottom">
                                                <p className="table_head">Estado de objetivo</p>
                                                <div className="row middle-xs">
                                                    {
                                                        boards && boards.map(
                                                        (boards, board) =>
                                                        <div key={board} className="col-xs-3">
                                                            <Input name="state" type="radio" classNameCustom="input_radio"
                                                            checked={boards.id == tasks.board} value={boards.id} id={boards.id}/>
                                                            <label htmlFor={boards.id}>{boards.name}</label>
                                                        </div>
                                                        )
                                                    }
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </section>
                            <section className="modal_section">
                                <div className="row middle-xs no-margin-left no-margin-right modal_section_title">
                                    <object width="20px" height="20px" data="./assets/img/icn_activity-blue.svg"></object>
                                    <div className="col-xs start-xs">
                                        <h4 className="semi-bold">Actividad</h4>
                                    </div>
                                </div>
                                <div className="col-xs-12 modal_section_content">
                                    {
                                        tasks.comments.length!=0 ?(
                                            tasks.comments.map((comments, i) => {
                                                return(
                                                    <div key={i} className="comment">
                                                        <div className="comment_box">
                                                            <p>{comments.body}</p>
                                                        </div>
                                                        <div className="comment_data row no-margin middle-xs">
                                                            <div className="col-xs start-xs">
                                                                <p>{comments.from}</p>
                                                            </div>
                                                            <div className="col-xs end-xs">
                                                                <p>{comments.date} a las {comments.hour} hs.</p>
                                                            </div>
                                                        </div>
                                                    </div>
                                                )
                                            })
                                        ):null                                
                                    }
                                </div>
                            </section>
                        </div>
                        <PostComment />
                    </Modal>
                </div>
            )
        )
    }
}

export default TaskCard;

这是Modal组件

//Modal.tsx file
//Dependencies
import * as React from 'react';

export interface ModalProps{
    onClose: any,
    show: boolean,
    children: any
}

export default class Modal extends React.Component<ModalProps>{
    handleStopPropagation = (e) =>{
        e.stopPropagation();
    }

    render(){
        const {onClose, show, children} = this.props;

        // Render nothing if the "show" prop is false
        if(!this.props.show) {
            return null;
        }

        return (
            <div className="modal_bkg" onClick={this.handleStopPropagation}>
                <div className="modal_bkg_container row middle-xs center-xs">
                    <div className="modal card">
                        <div className="right-align modal_close">
                            <button className="btn btn_close" onClick={this.props.onClose}>x</button>
                        </div>
                        {this.props.children}
                    </div>
                </div>
            </div>
        );
    }
}

2 个答案:

答案 0 :(得分:0)

我目前无法运行代码,但据我所知,TaskCard.render函数正在使用Array.map函数,该函数正在为每个任务项执行回调函数

并且存在问题,因为在回调中this不是您认为的this :)。根据文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map,您可以使用接受this的地图重载。

我相信如果你这样做

return(tasks && tasks.map(
            (tasks, key) => <div>put your component markup here</div>,
            this)
      );

TaskCard.render函数内,您应该不再看到错误。

答案 1 :(得分:0)

一位朋友帮助了我,现在它正在发挥作用。第一个问题是状态“isOpen”在开始时始终是未定义的,这就是为什么运行时抛出错误“无法读取未定义的属性'0'”。所以现在,“isOpen”是空对象,最终构造函数如下所示:

constructor(props) {
    super(props);

    this.state = { 
        isOpen: {}
    };
}

在此之后,另一个错误是“boards.map不是函数”,这是因为我将数组“板”作为对象传递。需要改变“董事会”。所以最终的代码是:

boards && boards.map(
    (board, key) =>
    <div key={key} className="col-xs-3">
       <Input name="state" type="radio" classNameCustom="input_radio"
       checked={board.id == task.board} value={board.id} id={board.id}/>
       <label htmlFor={board.id}>{board.name}</label>
    </div>
)

无论如何,谢谢你试图帮助我。此致!