CarlP
CarlP

Reputation: 201

React Class to Function components

I'm on the step of converting one of my Class components to a functional one, however, I'm thinking of better way of handling state from the functional version.

Currently, here is my Class component state:

this.state = {
      email: "",
      password: "",
      errors: {},
    };

On functional component version ,Currently I would have to break those states into three different states using UseState:

const [email, setEmail] = useState("");
const [password, setpassword] = useState("");
const [errors, setErrors] = useState({});

is there a way to combine these states in 1 state that is an object by default like this:

const [states,setStates] = useState({
    email:"",
    password:"",
    errors:{}
});

Reason why is because I have this kind of code from my class components, and I dont think this will work if I opted for the first Functional comp. setup:

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

Upvotes: 1

Views: 62

Answers (3)

Patrick Roberts
Patrick Roberts

Reputation: 51956

Yes you can achieve that using a custom hook:

const useLegacyState = initialState => {
  return useReducer((prevState, newState) => {
    return typeof newState === 'function'
    ? { ...prevState, ...newState(prevState) }
    : { ...prevState, ...newState };
  }, initialState);
};

And usage:

const [states, setStates] = useLegacyState({
  email: '',
  password: '',
  errors: {}
});

const handleChange = event => {
  setStates({
    [event.target.name]: event.target.value
  });
};

Upvotes: 1

Mohammad Faisal
Mohammad Faisal

Reputation: 2363

Yes you can do that. But you have to modify your setState Function like this


     handleChange = (event) => {
        setStates({ ...states , [event.target.name]: event.target.value})
     };

you have to do this on every setState call wherever you do .

Upvotes: 1

Kraylog
Kraylog

Reputation: 7563

Yes, the structure of the state variable is totally up to you.

Note, however, that this means that every time you call setStates you'll need to provide the entire structure.

You can use something like Object.assign to "update" existing state like this:

setStates(Object.assign({}, states, {a: 'b'}));

This would add the a key with a b value to the state, without changing previous ones.

Upvotes: 0

Related Questions