首页 > 解决方案 > React - .setState 部分不起作用

问题描述

我需要帮助来更新 React 中的状态。我正在使用 React 制作加密/解密表单。此 EncryptForm 在 App.js 中呈现。我想要做的是监听onSubmit函数并更新 isSubmitted 状态,然后decipher在“转换”按钮下渲染值。

我的问题是为什么.setStatehandleChange方法中起作用,但在方法中不起作用handleSubmit我错过了什么?(encryptMessage并且decryptMessage方法工作正常。)

这是 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

谢谢!

标签: javascriptreactjscomponentsstate

解决方案


您在 中错误地设置了状态handleSubmitnewState是整个状态对象,因此设置它this.setState({ newState })并不会更新整个状态,而是创建一个名为的新键newState并将其设置为您期望的状态。结果是这样的:

state = {
  ...previous_state,
  newState: {
    ...this.state,
    isSubmitted: true,
    decipher: decrypted
  },
}

相反,您可以执行以下操作来正确更新:

// desctructure so it overwrites each key
this.setState({ ...newState });

// pass the non-nested object
this.setState(newState);

或者首选的方法是只更新必要的密钥。this.setState与给定对象和前一个状态进行浅合并。所以你不需要这样做{...this.state}(事实上它是不鼓励的)。

这是最简洁准确的方法:

this.setState({ isSubmitted: true, decipher: decrypted });

推荐阅读