无法将状态变量用作功能参数?反应

时间:2018-07-02 22:23:44

标签: javascript reactjs

我在构造函数中声明一个状态变量。我在componentDidMount()中设置了新的状态,它成功设置了状态。但是我不能使用此状态变量来呈现菜单。 我的目标是使用从Firebase快照获取的数据来呈现菜单。

import React from 'react';
import PropTypes from 'prop-types';
import BScroll from 'better-scroll';
import './index.scss';
import Star from '../star';
import Split from '../split';
import {saveToLocal, loadFromLocal} from '@assets/js/store';

import {Card} from 'antd';
import {Menu, Dropdown, Button, Icon, message} from 'antd';
import {Input} from 'antd';
const {TextArea} = Input;
import {Row, Col} from 'antd';
import {List} from 'antd';
import Popup from "reactjs-popup";

import firebase from '../../firebase'; // <--- add this line

export default class needPage extends React.Component {

constructor(props, ctx) {
    super(props, ctx);
    this.state = {
        tableId: "A04",
        needList: [],
        comList: []
    };
}

componentDidMount() {
    this._initScroll();

    const needsRef = firebase.database().ref('needs').orderByChild('tableId').equalTo(this.state.tableId);
    needsRef.on('value', (snapshot) => {

        let allYourNeeds = snapshot.val();
        //console.log(allYourNeeds);
        //console.log(allYourOrders["foodOrders"]);
        let newstate = [];
        let needLists = allYourNeeds;
        for (let need in needLists) {
            //console.log((Date.now() - needLists[need].time)/ 1000 / 60);
            let diff = Math.round((Date.now() - needLists[need].time) / 1000 / 60);
            newstate.push({content: needLists[need].content, time: diff});
        }
        //console.log(allYourOrders["tableId"]);
        this.setState({needList: newstate});
    });

    const comNeedRef = firebase.database().ref('seller').child('comNeeds');
    comNeedRef.on('value', (snapshot) => {

        let allcomNeeds = snapshot.val();
        this.setState({comList: allcomNeeds});
    });
}

componentDidUpdate() {
    this._initScroll();
}

handleButtonClick(e) {
    message.info('您的需求已发送');
    //console.log(document.getElementById("customNeed").value);
    //console.log(Date.now());
    const itemsRef = firebase.database().ref('needs');
    const item = {
        tableId: "A03",
        content: document.getElementById("customNeed").value,
        time: Date.now()
    }
    itemsRef.push(item);
    document.getElementById("customNeed").value = document.getElementById("customNeed").defaultValue;

}

handleMenuClick(e) {
    message.info('需求也发送!');
    console.log('click', e);
}

recursion(dataSource) {
    console.log(dataSource);
    return (dataSource.map((menu, index) => {
        return (<Menu.Item key={menu.key}>{menu.title}</Menu.Item>)
    }))
}
menu = (<Menu onClick={this.handleMenuClick}>
    {this.recursion(this.state.comList)}
</Menu>);

gridStyle = {
    width: '100%',
    textAlign: 'left'
};

render() {
    return (<div className="seller" ref="seller">
        <div className="newNeed">
            <Row>
                <Col span={12} offset={2}>
                    <h1>新的需求</h1>
                </Col>
            </Row>
            <Row>
                <Col offset={2}>
                    <Dropdown overlay={this.menu}>
                        <Button className="dropdwNeed">常需需求
                            <Icon type="down"/></Button>
                    </Dropdown>
                </Col>
            </Row>
            <Row align="bottom">
                <Col span="span" ={15} offset={2}>
                    <div className="textArea">
                        <TextArea id="customNeed" placeholder="在这里手动输入您的需求" autosize="autosize"/>
                    </div>
                </Col>
                <Col span={3} offset={1}>
                    <Button className="submitButton" type="primary" onClick={this.handleButtonClick}>提交</Button>
                </Col>
            </Row>
        </div>
        <div className="ItemsNeed">
            <Row>
                <Col span={24} offset={2}>
                    <h1>您当下的需求</h1>
                </Col>
            </Row>
            <Row>
                <Col span={5} offset={2}>
                    <p className="title1">需求内容</p>
                </Col>
                <Col span={8} offset={8}>
                    <p className="title2">已需时间(分钟)</p>
                </Col>
            </Row>
            <Col offset={2}>
                <List className="listNeed" size="small" bordered="true" itemLayout="horizontal" dataSource={this.state.needList} renderItem={item => (<List.Item>
                        <List.Item.Meta title={item.content}/>
                        <div>{item.time}</div>

                    </List.Item>)}/>
            </Col>
            <Row>
                <h1 className="shuangji">(双击需求可以加急哦!)</h1>
            </Row>
        </div>
        <div className="tousu-contatiner">

            <Popup trigger={<Button className = "tousu" type = "danger" > 不满意!投诉!</Button>} modal="modal">
                {
                    close => (<div className="modal">
                        <a className="close" onClick={close}>
                            &times;
                        </a>
                        <div className="header">
                            投诉内容
                        </div>
                        <TextArea placeholder="在这里手动输入您的不满,我们会直接发送到店主邮箱" autosize="autosize"/>
                        <div className="actions">
                            <Button className="button" onClick={() => {
                                    console.log('modal closed ')
                                    close()
                                }}>提交投诉</Button>
                        </div>
                    </div>)
                }
            </Popup>
        </div>

    </div>);
}

toggleFavorite() {
    this.setState({
        favorite: !this.state.favorite
    });
    saveToLocal(this.context.seller.id, 'favorite', !this.state.favorite);
}

_initScroll() {
    this.scroll = new BScroll(this.refs.seller, {click: true});

}

}

needPage.contextTypes = {
seller: PropTypes.object
};

编译时出现的错误如下:

index.jsx:102 Uncaught TypeError: Cannot read property 'comList' of undefined
at new needPage (index.jsx:102)
at createClassProxy.js:98
at instantiate (createClassProxy.js:106)
at new needPage (eval at proxyClass (createClassProxy.js:112), <anonymous>:4:17)
at constructClassInstance (react-dom.development.js:11447)
at updateClassComponent (react-dom.development.js:13144)
at beginWork (react-dom.development.js:13824)
at performUnitOfWork (react-dom.development.js:15863)
at workLoop (react-dom.development.js:15902)
at HTMLUnknownElement.callCallback (react-dom.development.js:100)

2 个答案:

答案 0 :(得分:0)

不是应该是课程字段:

menu = (<Menu onClick={this.handleMenuClick}>
    {this.recursion(this.state.comList)}
</Menu>);
  1. 在构建组件时仅一次评估。即更新状态不会重新生成菜单。
  2. 此代码在this.state存在之前在构造函数的顶部执行,这就是为什么会出现此错误的原因。

将其移至render方法中。

答案 1 :(得分:0)

我使用componentWillMount()从firebase中获取数据并使用

<Menu>...</Menu>

直接在render方法中叠加。 问题解决了! 谢谢Felix和Tholle,他们俩都是正确的