反应:设置状态清除表单提交中的输入

时间:2020-05-14 06:34:10

标签: javascript reactjs

React的初学者在这里...

我制作了一个可以登录的API,如下所示:

// App.js
const [loginState, setLoginState] = useState([]);
    const handleLogin = async (e) => {
        e.preventDefault();
        const username = e.target.querySelector(".username");
        const password = e.target.querySelector(".password");
        const apiCall = await fetch(`${ROOT_URL}/api/login`, {
            method: "POST",
            headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                username: username.value,
                password: password.value
            })
        });
        const response = await apiCall.json();
        setLoginState(response)

    };

我的问题是,每次提交后,用户名和密码的输入值都会被清除。如何预防呢?似乎如果删除setLoginState,输入值将保留,但是理想情况下如何设置状态?如果登录失败,我的API会返回一些错误消息,我想向用户显示这些消息,并仍然在输入中保留用户名和密码值

我的登录组件如下:

function Login(props) {
    const { handleLogin, loginState } = props;
    const { from } = "/" || props.location.state;

    if (!loginState.isLoggedIn) {
        return (
            <div>
                <h1>Login</h1>
                <form onSubmit={handleLogin} >
                    <input className="username" type="text" name="username" />
                    <input className="password" type="password" name="password" />

                    <button>Log in</button>
                </form>
            </div>
        );
    } else {
        return <Redirect to={from ? from : "/"}/>
    }
};

3 个答案:

答案 0 :(得分:1)

设置状态后,React将重新渲染该组件,因此输入值将丢失。如果需要在重新渲染中保留值,则需要应用受控输入的概念:使输入值取决于组件状态,并在输入更改时更新组件状态,这将使您的组件设置为存储在状态中。这是一个示例:

class ControlledInput extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            foo: 'Intitial value',
            check: true
        }
    }
    _updateFoo = (ev) => {
        const value = ev.target.value;
        this.setState({foo:value});
    }
    _updateCheck = (ev) => {
        const value = ev.target.checked;
        this.setState({check: value});
    }
    render() {
        return (
            <form>
                <input name="foo" type="text" value={this.state.foo} onChange= 
                {this._updateFoo} />
                <input name="check" type="checkbox" checked={this.state.check} 
                onChange={this._updateCheck}/>
            </form>
        );
    }
}

您可以在此处了解更多信息:https://reactjs.org/docs/forms.html

答案 1 :(得分:0)

将值保存在状态中,并在状态本身的输入字段中呈现值。这是处理输入内容的受控方式。

function Login(props) {
    const { handleLogin, loginState } = props;
    const { from } = "/" || props.location.state;
    const [username, setUsername] = React.useState('');
    const [password, setPassword] = React.useState('');

    if (!loginState.isLoggedIn) {
        return (
            <div>
                <h1>Login</h1>
                <form onSubmit={handleLogin} >
                    <input className="username" type="text" name="username"
                       value={username} 
                       onChange={evt => setUsername(evt.target.value)} />
                    <input className="password" type="password" name="password"
                       value={password}
                       onChange={evt => setPassword(evt.target.value)} />

                    <button>Log in</button>
                </form>
            </div>
        );
    } else {
        return <Redirect to={from ? from : "/"}/>
    }
};

此外,要从handleLogin函数的这些输入字段中获取值,只需访问usernamepassword变量即可。

const handleLogin = async (e) => {
        e.preventDefault();

        const apiCall = await fetch(`${ROOT_URL}/api/login`, {
            method: "POST",
            headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                username,
                password
            })
        });
        const response = await apiCall.json();
        setLoginState(response)

    };

答案 2 :(得分:0)

在您的App.js中,您只需从登录组件获取凭据

const handleLogin = async (credentials) => {

const apiCall = await fetch(`${ROOT_URL}/api/login`, {
    method: "POST",
    headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(credentials)
});
const response = await apiCall.json();
};

并在此处取消您的提交,以便react不会刷新页面并使用

格式的onchange
function Login(props) {
const { handleLogin } = props;
const { from } = "/" || props.location.state;
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');

const login = (e) => {
    e.preventDefault();
    handleLogin({ username: username, password: password })
  }

if (!loginState.isLoggedIn) {
    return (
        <div>
            <h1>Login</h1>
            <form onSubmit={login} >
                <input className="username" onChange={e => setUsername(e.target.value)}  type="text" name="username" />
                <input className="password" onChange={e => setPassword(e.target.value)} type="password" name="password" />

                <button>Log in</button>
            </form>
        </div>
    );
} else {
    return <Redirect to={from ? from : "/"}/>
}
};