简体   繁体   English

反应 - .setState 部分不起作用

[英]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.我的问题是为什么.setStatehandleChange方法中有效,但在handleSubmit方法中handleSubmit What am I missing?我错过了什么? ( encryptMessage and decryptMessage methods are working fine.) encryptMessagedecryptMessage方法工作正常。)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM