[英]React - .setState is partially not working
I need help with updating the state in React.我需要帮助更新 React 中的状态。 I am making an Encryption/Decryption form with React.我正在使用 React 制作加密/解密表单。 This EncryptForm is rendered in App.js.此 EncryptForm 在 App.js 中呈现。 What I want to do is listen to onSubmit
function and update the isSubmitted state, then render decipher
value under the 'Convert' button.我想要做的是监听onSubmit
函数并更新 isSubmitted 状态,然后在“转换”按钮下呈现decipher
值。
My question is why .setState
works in handleChange
method but it doesn't work in handleSubmit
method.我的问题是为什么.setState
在handleChange
方法中有效,但在handleSubmit
方法中handleSubmit
。 What am I missing?我错过了什么? ( encryptMessage
and decryptMessage
methods are working fine.) ( encryptMessage
和decryptMessage
方法工作正常。)
Here is the EncryptForm component code.这是 EncryptForm 组件代码。
import React, { Component } from 'react'
import crypto from 'crypto'
class EncryptForm extends Component {
state = {
userInput: '',
isSubmitted: false,
decipher: ''
}
encryptMessage(input, key) {
// Initialization Vector - 16 bytes
const iv = new Buffer(crypto.randomBytes(16), 'utf8')
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv)
let encoded = cipher.update(input, 'utf8', 'base64')
encoded += cipher.final('base64')
return [encoded, iv, cipher.getAuthTag()]
}
decryptMessage(key, encoded, iv, authTag) {
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)
decipher.setAuthTag(authTag)
let text = decipher.update(encoded, 'base64', 'utf8')
text += decipher.final('utf8')
return text
}
/*
Non-encryption methods
*/
handleSubmit = event => {
event.preventDefault()
const KEY = new Buffer(crypto.randomBytes(32), 'utf8')
const [encrypted, iv, authTag] = this.encryptMessage(this.state.userInput, KEY)
const decrypted = this.decryptMessage(KEY, encrypted, iv, authTag)
const newState = {
...this.state,
isSubmitted: true,
decipher: decrypted
}
// THIS IS NOW UPDATING THE STATE :(
this.setState({ newState })
}
handleChange = event => {
this.setState({
[event.target.name]: event.target.value,
})
}
render() {
const { userInput, isSubmitted, decipher } = this.state
const isInvalid = userInput === ''
return (
<form onSubmit={this.handleSubmit}>
<input
type='text'
name='userInput'
placeholder='Encrypt this text...'
onChange={this.handleChange}
/>
<button disabled={isInvalid} type='submit'>Convert</button>
{isSubmitted && <p>{decipher.value}</p>}
</form>
)
}
}
export default EncryptForm
Thank you!谢谢!
You are setting state incorrectly in handleSubmit
.您在handleSubmit
错误地设置了状态。 newState
is the entire state object, so setting it like this.setState({ newState })
is not updating the whole state, but instead creating a new key called newState
and setting it to what you expect the state to be. newState
是整个状态对象,因此像this.setState({ newState })
一样设置它不会更新整个状态,而是创建一个名为newState
的新键并将其设置为您期望的状态。 The result is something like this:结果是这样的:
state = {
...previous_state,
newState: {
...this.state,
isSubmitted: true,
decipher: decrypted
},
}
Instead you could do something like this to correctly update:相反,您可以执行以下操作来正确更新:
// desctructure so it overwrites each key
this.setState({ ...newState });
// pass the non-nested object
this.setState(newState);
Or the preferred method would be to only update the keys necessary.或者首选方法是仅更新必要的密钥。 this.setState
does a shallow merge with the given object and the previous state. this.setState
与给定的对象和先前的状态进行浅层合并。 So you don't need to do {...this.state}
(in fact it is discouraged).所以你不需要做{...this.state}
(实际上这是不鼓励的)。
This is the most concise and accurate way:这是最简洁准确的方法:
this.setState({ isSubmitted: true, decipher: decrypted });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.