2017-08-02 63 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不是函数” –