如何以reactjs形式绑定数据

时间:2018-02-02 08:05:53

标签: javascript reactjs firebase firebase-realtime-database

我已经开始研究reactjs技术,我对这项技术来说是全新的。我希望将数据与我的下拉形式和下拉项目选择绑定我想要提供我的其他表单字段。在这里我创建表单为社会成员生成账单,我想填写社会成员名称绑定在drop下方框和帐单更改文本字段。有时我有问题说'TypeError:node is null'。我不明白如何将数据绑定到字段。

这是我的逻辑,请检查并让我知道我在这里错过了什么

 constructor(props, fdb) {
        super(props);

        this.state = {
            bill_nm: '',
            bill_eml: '',
            bill_total: '',
            bill_id: '',
            inputs:[],
            userInput:[]
        };
        this.userState = {
            user_id:'',
            email:'',
            first_name:'',
            last_name:''
        };
        this.chargeState ={
            charge_id:'',
            charge_title:'',
            charge_type:'',
            charge_amt:''
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmitFirebase = this.handleSubmitFirebase.bind(this);
        this.sendCallback = this.sendCallback.bind(this);
        this.appendInput = this.appendInput.bind(this);
        this.getInitialState = this.getInitialState.bind(this);
        this.appendUserInput = this.appendUserInput.bind(this);
        this.usercharge = [];

        const rootRef = DbConfig.database().ref();
        const post = rootRef.child('billing').orderByKey();
        const users = rootRef.child('users').orderByKey();
        const bill_charges = rootRef.child('billing_charges').orderByKey();

    }

    componentDidMount() {

             this.users.once('value', snap => {
            snap.forEach(child => {
                this.userState = {
                    user_id: child.key,
                    email: child.val().email,
                    first_name: child.val().first_name,
                    last_name: child.val().last_name
                };

            });

        });

        this.bill_charges.once('value', snap => {
            snap.forEach(child => {
                this.chargeState = {
                    chrage_key:child.key,
                    charge_id: child.charge_id,
                    charge_title: child.val().charge_title,
                    charge_type: child.val().charge_type,
                    charge_amt: child.val().charge_amt
                };
                this.usercharge = this.chargeState;
               //console.log( this.usercharge);
            });
        });

        }

           handleChange(event) {
        this.setState({ value: event.target.value });
    }


   getInitialState() {
        return {inputs:[]};
    }
    appendUserInput() {
        //e.preventDefault();

        // DbConfig.database().ref().child('users').orderByKey().once('value', snap => {
        //     snap.forEach(child => {
        //         this.userState = {
        //             user_id: child.key,
        //             email: child.val().email,
        //             first_name: child.val().first_name,
        //             last_name: child.val().last_name
        //         };
        //     });
        // });
        var newInput1 = this.state.userInput.length;
       // var newInput = this.userState.length;
        console.log('len1='+newInput1);
       // console.log('len'+newInput);
        this.setState({ userInput: this.state.userInput.concat(newInput1)});

    }
    appendInput(e) {
        e.preventDefault();
        var newInput = this.state.inputs.length;
            console.log('newinput'+newInput);
        this.setState({ inputs: this.state.inputs.concat(newInput)},function(){
            return;
        });
        console.log('input concate'+this.state.inputs);
    }

      render() {
        return (
            <div className="content">
                <NavBar></NavBar>
                <div className="row">
                    <div className="col-md-10">
                        <div className="card">
                            <div className="card-header card-header-icon" data-background-color="rose">
                                <i className="material-icons">receipt</i>
                            </div>
                            <div className="card-content">
                                <h4 className="card-title">Add Bill</h4>
                                <form onSubmit={this.handleSubmitFirebase}>
                                    <div className="form-group label-floating is-empty">
                                        <label className="control-label">Person Name</label>

                                        <div className="room-main">
                                        <div className="online-est">                                         
                                                <a href="javascript:void(0);" onClick={this.appendUserInput} className="rednew-btn"><i className="fa fa-plus-circle"></i> Add user</a>
                                            <select className="room-form">
                                           {this.state.userInput.map(function(item){
                                               console.log('i'+item);
                                                return (
                                                          <option ref={item}>{item}</option> 
                                                       )
                                           })}
                                           </select>
                                        </div>
                                    </div>
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                    <label className="control-label">Person Name</label>
                                        <div className="room-main">
                                        <div className="online-est"> 
                                                <a href="javascript:void(0);" onClick={this.appendInput} className="rednew-btn"><i className="fa fa-plus-circle"></i> Add charge</a>
                                            <select>
                                           {this.state.inputs.map(function(item){
                                                return (
                                                            <option ref={item}>{item}</option>
                                                       )
                                           })}
                                           </select>
                                        </div>
                                    </div>
                                    <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                            <label className="control-label">status</label>
                                            <select>
                                                <option value="Unpaid">Unpaid</option>
                                                <option value="Paid">Paid</option>
                                            </select>
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                            <label className="control-label">total</label>
                                            <input type="text" className="form-control" ref={el => this.billtotal = el} onChange={this.handleChange} />
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                            <label className="control-label">Bill period</label>
                                            <input type="date" className="form-control" ref={el => this.billto = el} onChange={this.handleChange} />
                                            <input type="date" className="form-control" ref={el => this.billfrom = el} onChange={this.handleChange} />
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                        <span className="material-input"></span></div>
                                    <button type="submit" className="btn btn-fill btn-rose">Submit</button>
                                </form>
                            </div>
                        </div>
                    </div>

                </div>
            </div>
        )
    }

3 个答案:

答案 0 :(得分:2)

您可以使用构造函数,在构造函数中初始化状态并在构造函数中绑定您的方法,而不是使用get初始状态。

constructor(props) {
  super(props);
  this.state = {
    listVisible: false
  };
 this.select = this.select.bind(this)
 this.show = this.show.bind(this)
 this.hide = this.hide.bind(this)
 this.renderListItems = this.renderListItems.bind(this)
}

然后当您在渲染方法中调用select时,您应该只能说...

<div onClick={this.select(item)}>
  <span>{item.name}</span>
</div> 

虽然您需要在响应中添加一个键来跟踪列表,因此将第一行更改为<div key={i} onClick={this.select(item)}>。您可以单独阅读密钥https://reactjs.org/docs/lists-and-keys.html#keys

答案 1 :(得分:1)

<div className="post">
  <h3>{this.state.bill_nm}</h3>
  <h2>{this.state.bill_eml}</h2>
  <p>{this.state.bill_total}</p>
</div>

上面的这些状态值从未定义过。您需要在初始状态下定义它们,或者在它们被调用之前设置它们。

在渲染中输入的onChange处理程序中,您正在调用this.handleChange,但它们也没有被定义。

<input type="text" className="form-control" ref={el => this.pnm = el} onChange={this.handleChange} />

我认为此代码示例不完整。

要回答标题问题,本文将介绍您在反应https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56中绑定this的选项

答案 2 :(得分:0)

作为替代方案,您可以尝试Redux Form https://redux-form.com,它将为您完成大部分工作