2017-06-18 6 views
0

こんにちは!反応変数がjsxで変化する

私はチュートリアルの後に遊んでいて、わからない問題を見つけました。

私は、彼らがupdateSurveyText={this.updateSurvey.bind(i, newText[0], newText[1])}

に入るとき、彼らは戻って古い変数への変更this.props.updateSurveyText(this.props.index, newText)て変数を渡すたびロギングは最初の関数の右の変数を示しますが、私は第二の機能でそれらをログインしたとき、彼らは変更されません。

お願いします。

調査:

import React from 'react'; 
import ReactDOM from 'react-dom'; 

export default class Survey extends React.Component{ 
    constructor(props){ 
    super(props); 
    this.state = { 
     editing : false, 
     title : "", 
     desc : "", 
    }; 
    this.edit = this.edit.bind(this); 
    this.save = this.save.bind(this); 
    this.remove = this.remove.bind(this); 
    } 

    edit() { 
    this.setState({editing: true}); 
    } 

    remove() { 
    console.log('delete'); 
    this.props.deleteFromBoard(this.props.index) 
    } 

    save() { 
    var title = this.refs.newTitle.value; 
    var desc = this.refs.newDesc.value; 
    var newText = [title, desc]; 
    console.log(newText[0]); 
    this.props.updateSurveyText(this.props.index, newText); 
    this.setState({editing: false}); 
    } 

    renderNormal(){ 
    return(
     <div className="surveyContainer"> 
     <div className="surveyTitle">{this.props.children[0]}</div> 
     <div className="surveyDesc">{this.props.children[1]}</div> 
     <button onClick={this.edit} className="button-primary">Edit</button> 
     <button onClick={this.remove} className="button-primary">Remove</button> 
     </div> 
    ); 
    } 

    renderForm(){ 
    return(
     <div className="surveyContainer"> 
     <textarea ref="newTitle" defaultValue={this.props.children[0]}></textarea> 
     <textarea ref="newDesc" defaultValue={this.props.children[1]}></textarea> 
     <button onClick={this.save} className="button-primary">Save</button> 
     </div> 
    ); 
    } 

    render(){ 
     if(this.state.editing){ 
     return this.renderForm(); 
     }else{ 
     return this.renderNormal(); 
     } 
    } 
} 

会:

import Survey from './Survey.jsx'; 
import React from 'react'; 
import ReactDOM from 'react-dom'; 

export default class Board extends React.Component{ 
    constructor(props){ 
    super(props); 
    this.state = { 
     surveys: [ 

     ], 
    }; 
    this.updateSurvey = this.updateSurvey.bind(this); 
    this.removeSurvey = this.removeSurvey.bind(this); 
    this.eachSurvey = this.eachSurvey.bind(this); 
    this.addSurvey = this.addSurvey.bind(this); 
    } 

    addSurvey(title, desc){ 
    var arr = this.state.surveys; 
    arr.push([title, desc]); 
    this.setState({surveys: arr}) 
    } 

    removeSurvey(i){ 
    var arr = this.state.surveys; 
    arr.splice(i, 1); 
    this.setState({surveys: arr}) 
    } 

    updateSurvey(newTitle, newDesc, i){ 
    console.log(newTitle);console.log(newDesc); 
    var arra = this.state.surveys; 
    arra[i] = [newTitle, newDesc]; 
    this.setState({surveys: arra}); 

    } 

    eachSurvey(newText, i){ 
    return(
     <Survey key={i} index={i} updateSurveyText={this.updateSurvey.bind(i, newText[0], newText[1])} deleteFromBoard={this.removeSurvey.bind(i)}> 
     {newText[0]} 
     {newText[1]} 

     </Survey>); 
    } 

    render(){ 
    return(
     <div> 
     <button onClick={this.addSurvey.bind(null, "Titel", "Desc")}>Add new</button> 
     <div className="board"> 
      {this.state.surveys.map(this.eachSurvey)} 
     </div> 
     </div> 
    ) 
    } 
} 

答えて

0

あなたupdateSurvey機能は3つの引数を受け入れます。

updateSurvey(newTitle, newDesc, i)

あなたは機能上.bindを呼び出すときは、「ターゲット関数を呼び出すときにバインドされた関数に渡された引数に先頭に追加する引数を。」を提供していますあなたは

updateSurveyText={this.updateSurvey.bind(i, newText[0], newText[1])}

を呼び出すときに、それが呼ばれるたびにupdateSurveyTextとして受け継が機能が永久にその引数リストの先頭に付加二つの引数を持っていることを意味Function.prototype.bind

.bindが呼び出された時点であったnewText[0]newText[1]の値は、updateSurveyTextが呼び出されるたびに第1引数と第2引数として使用されます。それをクリアするための

function add(first, second) { 
 
    console.log('add called with args: ', first, second); 
 
    console.log('all arguments: ', [].slice.call(arguments)); 
 
    return first + second; 
 
} 
 

 
document.write('add(1, 1) = ' + add(1, 1)); 
 
document.write('<br>'); 
 

 
var boundAdd = add.bind(null, 1, 1); 
 

 
// despite passing new arguments, 2 and 2, the 
 
// bound function has 1 and 1 bound to it and will not 
 
// use 2 and 2 as the first and second arg. 
 
// 1 and 1 are prepended to the arguments list. 
 
document.write('boundAdd(2, 2) = ' + boundAdd(2, 2));

+0

おかげで、原因結合にaswellいくつかの奇妙な行動を説明します。

は、ここでの例です。しかし、バインディングなしで状態を更新する方法やバインディングを別々に使用する方法としてはあまりよく分かりません。問題を解決する方法としてヒントを教えてください。 – Conroyd

+0

'updateSurveyText'に渡すときに' updateSurvey'に変数をバインドしないでください。あなたのSurveyコンポーネントにはすでに索引が付いており、テキスト値はあなたの参考文献から取得されます。 'updateSurveyText = {this.updateSurvey}'を渡して 'save'関数で正しい引数' this.props.updateSurveyText(newTitle、newDesc、this.props.index);を呼び出すだけです。テキスト部分を配列にラップします。第3引数として 'this.props.index'を渡してください。あなたの例は、引数が順不同です。 – jbielick

+0

ありがとうございました!しかし、あなたが私のupdateSurvey関数で見るように、私は状態を以下のように呼び出します:var arra = this.state.surveys;これは型エラーとなります:this.stateは未定義です。関数に状態を渡す必要がありますか? – Conroyd

関連する問題