反应状态挂钩问题

时间:2020-07-02 12:34:47

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

我正在尝试使用状态挂钩来使onChange与material-ui一起正确处理错误文本。但是得到一个问题。我已附上控制台中出现的错误屏幕。 enter image description here

这是我的代码:

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>
    );
}

我想我在这里缺少了以适当方式使用状态挂钩的重要内容。 任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:3)

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

setDataAction(prevState => {
 prevState.errorNameText = '';
});
  1. 对于箭头函数,如果要隐式返回对象,则需要用()

    进行包装
  2. 您正在改变状态。请勿将其设置为prevState.errorNameText = ''

这是正确的方法:

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

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

答案 1 :(得分:2)

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: '';
})

答案 2 :(得分:2)

更改

var intervalloNavicella = setInterval(function() {
  if (accese == true) {
    var imageUrlSpacecrafat = "bk-nav-0" + currArea;
    $("#spacecraft").css(
      "background-image",
      "url(assets/img/" + imageUrlSpacecrafat + ".png)"
    );
    accese = false;
  } else {
    var imageUrlSpacecrafat = "bk-nav-0" + currArea + "-b";
    $("#spacecraft").css(
      "background-image",
      "url(assets/img/" + imageUrlSpacecrafat + ".png)"
    );
    accese = true;
  }
}, 500);

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

请让我知道它是否解决了,然后我会详细说明。