【问题标题】:React state hook issue反应状态钩子问题
【发布时间】:2020-10-23 01:25:23
【问题描述】:

我正在尝试使用状态挂钩使 onChange 与 material-ui 一起正常工作以处理错误文本。但是遇到一个问题。我已经附上了控制台中出现的错误屏幕。

这是我的代码:

import React, { Component, useState } from 'react';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';

export const CreateForm = (props) => {
    const { containerClass } = props;
    let [dataAction, setDataAction] = useState({ errorNameText: 'Enter product name!' });
    let errorNameText = 'Enter the name!';

    const handleNameChange = (event) => {
        const name = event.target.value;
        if(name && name !== '') {
            setDataAction(prevState => {
                prevState.errorNameText = '';
            })
        }
    }
    return(
        <div className={containerClass}>
            <div>
                <TextField
                    className="product_nameField"
                    floatingLabelText="Product Name"
                    errorText={dataAction.errorNameText}
                    onChange={handleNameChange}
                />
            </div>
            <br/>
            <div>
                <TextField
                    className="product_priceField"
                    floatingLabelText="Product Price"
                />
            </div>
            <br/>
            <div>
                <TextField
                    className="product_infoField"
                    floatingLabelText="Product Info"
                />
            </div>
            <br/>
            <div>
                <RaisedButton label="Submit" primary={true} />
            </div>
        </div>
    );
}

我想我在这里错过了以正确方式使用状态挂钩的重要内容。 任何帮助将不胜感激。

【问题讨论】:

    标签: javascript reactjs material-ui react-hooks textfield


    【解决方案1】:

    您以错误的方式设置状态。这里有两个问题:

    setDataAction(prevState => {
     prevState.errorNameText = '';
    });
    
    1. 对于箭头函数,如果你想隐式返回一个对象,你需要用()包裹它

    2. 你正在改变你的状态。不要设置成prevState.errorNameText = ''

    这是正确的方法:

    setDataAction(prevState => ({
     ...prevState,
     errorNameText: '';
    }));
    

    因此,您应该传播当前状态并进行必要的更改。在您的情况下,您没有任何其他属性,但这是正确的方法。因为,如果您将来向您的状态添加另一个属性并且在此处不使用扩展语法,您将丢失您状态中的所有其他属性。

    【讨论】:

    • 谢谢devserkan,已经解决了。实际上,我是使用 react hooks 的新手,错过了重要的注意事项。
    • 如果您要使用公认答案的方法,请注意我使用扩展语法的说明。如果您不使用它,可能会在以后导致一些问题。就您而言,目前还可以,但正如我试图在回答中解释的那样,请记住潜在的问题。
    • 感谢 devserkan,当然,我会记住这一点。 Pease 将 '=' 更改为 ':' 因为它给出了错误
    【解决方案2】:

    改变

    const handleNameChange = (event) => {
        const name = event.target.value;
        if(name && name !== '') {
            setDataAction(prevState => {
                prevState.errorNameText = '';
            })
        }
    }
    

       const handleNameChange = (event) => {
            const name = event.target.value;
            if(name && name !== '') {
                 setDataAction({ errorNameText: ''})   <------ CHANGED
            }
        }
     
    

    如果解决了请告诉我,然后我会详细说明。

    【讨论】:

    • 谢谢,解决了。实际上,我是使用 react hooks 的新手,错过了重要的注意事项。
    【解决方案3】:

    setDataAction 会将状态的值设置为传递的值或如果您传递函数则返回的值

    你的函数只是改变了之前的状态,然后什么也不返回。因此,下一次渲染 dataAction 将是未定义的,您将尝试执行 dataAction.errorNameText 并崩溃。

    使用

    // no point to use this syntax since the new state
    // does not depend on the previous state 
    setDataAction(prevState => ({ 
        errorNameText: '';
    }))
    

    // use this syntax for your use case
    setDataAction({
        errorNameText: '';
    })
    

    【讨论】:

    • 谢谢@Gabriele,解决了。实际上,我是使用 react hooks 的新手,错过了这里的重要说明。
    • 嗨 Gabriele,另一件事,请将 '=' 更改为 ':',因为它给出了错误
    猜你喜欢
    • 2021-11-22
    • 2021-10-12
    • 2020-01-31
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2022-11-01
    • 2020-12-20
    • 1970-01-01
    相关资源
    最近更新 更多