React-.setState部分不起作用

时间:2020-03-06 21:35:50

标签: javascript reactjs components state

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

我的问题是为什么.setState可以在handleChange方法中工作,而不能在handleSubmit方法中使用。我缺少什么? (encryptMessagedecryptMessage方法工作正常。)

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

谢谢!

1 个答案:

答案 0 :(得分:1)

您在handleSubmit中错误地设置了状态。 newState是整个状态对象,因此将其设置为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 });