Javascript 无法将状态变量用作函数参数?反应

Javascript 无法将状态变量用作函数参数?反应,javascript,reactjs,Javascript,Reactjs,我在构造函数中声明一个状态变量。我在componentDidMount()中设置了新状态,它成功地设置了状态。但是我不能使用这个状态变量来呈现我的菜单。 我的目标是用我从firebase快照获得的数据呈现菜单 import React from 'react'; import PropTypes from 'prop-types'; import BScroll from 'better-scroll'; import './index.scss'; import Star from '../s

我在构造函数中声明一个状态变量。我在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
};
从“React”导入React;
从“道具类型”导入道具类型;
从“更好的卷轴”导入BScroll;
导入“/index.scss”;
从“../Star”导入星号;
从“../Split”导入拆分;
从'@assets/js/store'导入{saveToLocal,loadFromLocal};
从“antd”导入{Card};
从“antd”导入{菜单、下拉菜单、按钮、图标、消息};
从“antd”导入{Input};
const{TextArea}=输入;
从“antd”导入{Row,Col};
从“antd”导入{List};
从“reactjs弹出窗口”导入弹出窗口;
从“../../firebase”;/”导入firebase{
让allYourNeeds=snapshot.val();
//console.log(所有您需要的);
//log(所有您的订单[“foodOrders”]);
让newstate=[];
让需求列表=你所有的需求;
for(让需求列表中的需求){
//console.log((Date.now()-needLists[need].time)/1000/60);
让diff=Math.round((Date.now()-needLists[need].time)/1000/60);
push({content:needLists[need].content,time:diff});
}
//log(allYourOrders[“tableId]”);
this.setState({needList:newstate});
});
const comNeedRef=firebase.database().ref('seller').child('comNeeds');
comNeedRef.on('值',(快照)=>{
让allcomNeeds=snapshot.val();
this.setState({comList:allcomNeeds});
});
}
componentDidUpdate(){
这个;
}
把手按钮(e){
message.info('您的需求已发送');
//console.log(document.getElementById(“customneeded”).value);
//console.log(Date.now());
const itemsRef=firebase.database().ref('needs');
常数项={
表ID:“A03”,
内容:document.getElementById(“CustomNeeded”).value,
时间:Date.now()
}
项目推送(项目);
document.getElementById(“CustomDemand”).value=document.getElementById(“CustomDemand”).defaultValue;
}
手柄菜单(e){
message.info('需求也发送!');
console.log('click',e);
}
递归(数据源){
console.log(数据源);
返回(dataSource.map)((菜单,索引)=>{
返回({menu.title})
}))
}
菜单=(
{this.recursion(this.state.comList)}
);
网格样式={
宽度:“100%”,
textAlign:'左'
};
render(){
返回(
新的需求
常需需求
提交
您当下的需求

需求内容

已需时间(分钟)

( {item.time} )}/> (双击需求可以加急哦!) { 关闭=>( &时代; 投诉内容 { console.log('modal closed') 关闭() }}>提交投诉 ) } ); } toggleFavorite(){ 这是我的国家({ 收藏夹:!this.state.favorite }); saveToLocal(this.context.seller.id,'favorite',!this.state.favorite); } _initScroll(){ this.scroll=new BScroll(this.refs.seller,{click:true}); } } needPage.contextTypes={ 卖家: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)
index.jsx:102未捕获类型错误:无法读取未定义的属性“comList”
在新的需求页面(index.jsx:102)
在createClassProxy.js:98
实例化时(createClassProxy.js:106)
在新的needPage上(在proxyClass(createClassProxy.js:112)上求值):4:17
在constructClassInstance(react dom.development.js:11447)
在updateClassComponent(react dom.development.js:13144)
开始工作时(react dom.development.js:13824)
执行工作时(react dom.development.js:15863)
在workLoop(react dom.development.js:15902)
在htmlunknowneelement.callCallback(react dom.development.js:100)

这应该不是一个类字段:

menu = (<Menu onClick={this.handleMenuClick}>
    {this.recursion(this.state.comList)}
</Menu>);
菜单=(
{this.recursion(this.state.comList)}
);
  • 当构建组件时,仅对其进行一次评估,即更新状态不会重新生成菜单
  • 此代码在
    This.state
    存在之前在构造函数顶部执行,这就是为什么会出现该错误
  • 将其移动到
    render
    方法中。

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

    <Menu>...</Menu>
    
    。。。
    
    直接在渲染方法中覆盖。 问题解决了
    感谢Felix和Thole,他们都是对的

    你能包括你的整个组件,包括渲染方法吗?很难说问题中的代码有什么问题。你好Thole感谢我的问题:)如果你只给你的