在不同条件下反应调用方法

时间:2017-11-09 18:53:36

标签: javascript reactjs methods

我是初学者,我已经编写了以下代码:

class Note extends React.Component {
   constructor(props) {
       super(props);
       this.state = {editing: false};

        this.edit = this.edit.bind(this);
        this.save = this.save.bind(this);

   }

   edit() {
       // alert('edit');
       this.setState({editing: !this.state.editing});
   }

   save() {
       this.props.onChange(this.refs.newVal.value, this.props.id);
       this.setState({editing: !this.state.editing});
       // console.log('save is over');
   }

   renderForm() {
       return (
           <div className="note">
               <textarea ref="newVal"></textarea>
               <button onClick={this.save}>SAVE</button>
           </div>
       );
   }

   renderDisplay() {
       return (
           <div className="note">
               <p>{this.props.children}</p>
               <span>
                         <button onClick={this.edit}>EDIT</button>
                        <button onClick={this.remove}>X</button>
               </span>
           </div>
       );
   }

   render() {
       console.log(this.state.editing);
       return (this.state.editing) ? this.renderForm()
           : this.renderDisplay()

   }
}

class Board extends React.Component {

   constructor(props){
       super(props);

       this.state = {
           notes: []
       };

       this.update = this.update.bind(this);
       this.eachNote = this.eachNote.bind(this);
       this.add = this.add.bind(this);
   }

   nextId() {
       this.uniqeId = this.uniqeId || 0;
       return this.uniqeId++;
   }

   add(text) {
       let notes = [
           ...this.state.notes,
           {
               id: this.nextId(),
               note: text
           }
       ];

       this.setState({notes});
   }

   update(newText, id) {
       let notes = this.state.notes.map(
           note => (note.id !== id) ?
               note :
               {
                   id: id,
                   note: newText
               }
       );
       this.setState({notes})
   }

    eachNote(note) {
       return (<Note key={note.id}
                     id={note.id}
                     onChange={this.update}>

           {note.note}
       </Note>)
   }

   render() {
       return (<div className='board'>
           {this.state.notes.map(this.eachNote)}
           <button onClick={() => this.add()}>+</button>
       </div>)
   } 
}

ReactDOM.render(<Board />,
   document.getElementById('root'));

在render()中,onClick事件有一个函数,即如果以这种方式使用: {this.add} ,则会创建以下错误:

  

未捕获错误:对象无效作为React子对象(找到:具有键的对象{dispatchConfig,_targetInst,nativeEvent,type,target,currentTarget,eventPhase,bubbles,cancelable,timeStamp,defaultPrevented,isTrusted,view,detail ,. ..})

为什么呢?而在eachNote()方法中使用此命令:

  

的onChange = {this.update}

没有错误。

有人可以告诉我原因吗?感谢。

3 个答案:

答案 0 :(得分:2)

问题是在add函数中你正在使用参数文本并将其设置为状态,所以当你调用onClick={() => this.add()}时,你没有传递任何参数来添加函数,因此在它的定义中{{1未定义,因此text设置为未定义。

但是,如果您直接将其称为state noteonClick={this.add}函数会将add对象作为参数接收,因此它将event设置为您的事件对象正在使用state note

答案 1 :(得分:1)

onClick={this.add}会将点击事件传递给this.add

所以你需要做的是:

onClick={e => this.add('some text')}或类似的。

如果您想onClick={this.add},则必须确保添加方法为:add(event) { ... }

答案 2 :(得分:0)

<Note />组件不包含render()方法来返回任何内容。添加render()方法并返回一些内容。

class Note extends React.Component {
   constructor(props) {
       super(props);
       this.state = {editing: false};

        this.edit = this.edit.bind(this);

   }

   edit() {
       // alert('edit');
       this.setState({editing: !this.state.editing});
   }
   
   render() {
     return (
       <div>Render something</div>
     )
   }
}

class Board extends React.Component {

   constructor(props){
       super(props);

       this.state = {
           notes: []
       };

       this.update = this.update.bind(this);
       this.eachNote = this.eachNote.bind(this);
       this.add = this.add.bind(this);
   }

   nextId() {
       this.uniqeId = this.uniqeId || 0;
       return this.uniqeId++;
   }

   add(text) {
       let notes = [
           ...this.state.notes,
           {
               id: this.nextId(),
               note: text
           }
       ];

       this.setState({notes});
   }

   update(newText, id) {
       let notes = this.state.notes.map(
           note => (note.id !== id) ?
               note :
               {
                   id: id,
                   note: newText
               }
       );
       this.setState({notes})
   }

    eachNote(note) {
       return (<Note key={note.id}
                     id={note.id}
                     onChange={this.update}>

           {note.note}
       </Note>)
   }

   render() {
       return (<div className='board'>
           {this.state.notes.map(this.eachNote)}
           <button onClick={() => this.add()}>+</button>
       </div>)
   } 
}

ReactDOM.render(<Board />,
   document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>

<div id="root"></div>