简体   繁体   中英

Updating MaterialUI's “TextField” value causes other TextField values on the page to clear

I'm trying to update the label of a TextField when ever a change is detected in its input.

Here's my state initially:

state = {
    loginDetails: {
        email: "email@gmail.com",
        password: "password"
    },
    isLoading: false,
    error: null
};

Here's what my MatUI TextField elements look like:

<TextField
    type="text"
    name="email"
    label="email"
    value={this.state.loginDetails.email || ""}
    variant="outlined"
    onChange={this.change}
/>
<TextField
    type="password"
    name="password"
    label="password"
    value={this.state.loginDetails.password || ""}
    variant="outlined"
    onChange={this.change}
/>

Whenever a change is detected within the TextField itself, this function fires:

change = event => {
    this.setState({
        loginDetails: { [event.target.name]: event.target.value }
    });
};

I believe this line: loginDetails: { [event.target.name]: event.target.value } is the problem.

If my state looked like the following, with the following change function, everything works as expected and there is no clearing/resetting:

state = {
    email: "email@gmail.com",
    password: "password"
    isLoading: false,
    error: null
};

...

change = event => {
    this.setState({ [event.target.name]: event.target.value });
};

But, I want the email and password to be in its own object, for a multitude of reasons.

Here's what the page looks like on initial load

Here's what happens after clicking into the password field and typing a character (the email field clears)

You are right, issue is here

this.setState({
    loginDetails: { [event.target.name]: event.target.value }
});

this will either keep username or password , coz you are assigning only one field loginDetails: { [event.target.name]: event.target.value } ,

So Change it to:

this.setState((state) => {
    loginDetails: {
        ...state.loginDetails, // <--- get username and password
        [event.target.name]: event.target.value // <--- over write the field
    }
});

From your code

change = event => {
    this.setState({
        loginDetails: { [event.target.name]: event.target.value }
    });
};

You replaced loginDetails with an object with a single field (event.target.name)

Try merging the object instead of replacing it.

For example

change = event => {
    const newLoginDetails = Object.assign(
        {},  
        this.state.loginDetails,
        { [event.target.name]: event.target.value }
    )
    this.setState({
        loginDetails: newLoginDetails
    });
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM