2017-08-02 101 views
2

我目前在學習Reactjs,並且想要做一個簡單的Caeser-En/Decryption(移位字符)。Reactjs函數發射兩次?

當文本輸入發生變化時它可以正常工作,但似乎如果加密密鑰正在更改(updateRot()),則CaeserShift函數會觸發兩次(甚至更頻繁?)。

但我無法弄清楚我做錯了什麼。

class MarkdownEditor extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.handleChange = this.handleChange.bind(this); 
 
    this.updateRot = this.updateRot.bind(this); 
 
    this.state = {value: 'abcdefghijklmnopqrstuvwxyz', 
 
        rot: 1 
 
       }; 
 
    } 
 
    
 
    updateRot(e){ 
 
    this.setState({ 
 
     rot: e.target.value  
 
    }); 
 
    } 
 
    
 
    handleChange(e){ 
 
    this.setState({ 
 
     value: e.target.value 
 
     }); 
 
    } 
 

 
caesarShift(str, amount){ 
 

 
\t var output = ''; 
 
\t // Go through each character 
 
\t for (var i = 0; i < str.length; i ++) { 
 

 
\t \t // Get the character we'll be appending 
 
\t \t var c = str[i]; 
 

 
\t \t // If it's a letter... 
 
\t \t if (c.match(/[a-z]/i)) { 
 

 
\t \t \t // Get its code 
 
\t \t \t var code = str.charCodeAt(i); 
 
\t \t \t // Uppercase letters 
 
\t \t \t if ((code >= 65) && (code <= 90)) 
 
\t \t \t \t c = String.fromCharCode(((code - 65 + amount) % 26) + 65); 
 

 
\t \t \t // Lowercase letters 
 
\t \t \t else if ((code >= 97) && (code <= 122)) 
 
\t \t \t \t c = String.fromCharCode(((code - 97 + amount) % 26) + 97); 
 
     
 
\t \t } 
 
\t \t // Append 
 
\t \t output += c; 
 
\t } 
 
\t // All done! 
 
    return output 
 
    
 
}; 
 

 
    render() { 
 
    return (
 
     <div className="MarkdownEditor"> 
 
     <div className="Input"> 
 
     <h3>Input</h3> 
 
     <textarea 
 
      rows="2" 
 
      onChange={this.handleChange} 
 
      defaultValue={this.state.value} 
 
      /> 
 
     </div> 
 
     <div> 
 
     <p>{this.state.rot}</p> 
 
     
 
     <input className="quantity-input__screen" type="text" defaultValue={this.state.rot} onChange={this.updateRot} /> 
 
      
 
     </div> 
 
     <div className="Output"> 
 
     <h3>Output</h3> 
 
     <textarea 
 
      rows="2" 
 
      className="content" 
 
      value={this.caesarShift(this.state.value, this.state.rot)} 
 
     /> 
 
     </div> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<MarkdownEditor />, document.getElementById('app'));
.MarkdownEditor div{ 
 
    
 
    box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); 
 
    display:block; 
 
    
 
} 
 
.MarkdownEditor div textarea{ 
 
    -webkit-box-sizing: border-box; 
 
\t -moz-box-sizing: border-box; 
 
\t box-sizing: border-box; 
 
    display:block; 
 
\t width: 100%; 
 
    overflow-y:auto;/*resets IE*/ 
 
    overflow-x:hidden;/*resets IE*/ 
 
} 
 
.MarkdownEditor { 
 
    padding-left: 25%; 
 
    padding-right: 25%; 
 
    
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="app"></div>

編輯: 得到了解決! this.state.rot不是int!

...

caesarShift(str, rot){ 

     var amount = parseInt(rot)||0; 

...

+0

每當你正在更新的加密密鑰存儲,你有一個onChange事件,在其中設置的狀態,所以,每當你設置狀態組件被重新渲染和函數被再次調用 –

+0

好吧,但爲什麼它能正常工作,只要我只改變輸入文本?它不應該是相同的效果? –

回答

2

如果你想通過道具參數傳遞給函數,你應該括在一個箭頭的功能,否則你基本上是調用該函數。您可以撥打caeserShift並將其傳遞給該州。

handleChange(e){ 

    this.setState({ 
     value: e.target.value, 
     encrypted: this.caeserShift(e.target.value, this.state.rot) 
    }); 
} 

然後你就可以在這個值textarea的

value={this.state.encrypted}

+1

這樣你沒有通過函數返回的值,但函數本身 –

+0

嗯,你是對的 – Emobe

+0

我已經試過這個。它似乎無法在setState中調用caeserShift。 「TypeError:this.caeserShift不是函數」 –