samedi 31 octobre 2020

What is the best way to set object properties when filling a complex form in React

I'm new in React. I have what seems like a standard task: fill in the form data about a user and send it to the server. The form is a set of components, such as: Basic information, Passport data, Hobbies, etc. + Save button.

I did it in the following way. There is a class describing the model. When creating a component, I create an instance of this class in useRef. Further, I pass this model variable to all child components through their props. Model properties are populated in components. So when I click on the Save button I have the model properties filled in. Here's an example.

Please tell me, is this a good approach for filling in the data of a complex object? Maybe it's better to do it different way? Are there any best practices? Maybe I should use redux for this task?

model.ts

 class Model {
      // Component 1
      firstName: string;
      lastName: string;
    
      // Component 2
      passport: string;
      address: string;
    }
    
    interface IComponent {
      model: Model;
    }
    
    export { Model, IComponent };

index.tsx

export const App: React.FunctionComponent<{}> = () =>
{
 const model = useRef<Model>(new Model());

 const save = () =>{
   console.log(model.current);
 }

return (
  <React.Fragment>
    <Component1 model={model.current} />
    <Component2 model={model.current} />
    <button onClick={save}>Сохранить</button>
  </React.Fragment>
);
}
render(<App />, document.getElementById('root'));

Component1.tsx

export const Component1: React.FunctionComponent<IComponent> = ({ model }) => {

  const [firstNameValue, setFirstNameValue] = useState(model.firstName);
  const [lastNameValue, setLastNameValue] = useState(model.lastName);

  const changeFirstName = (e: React.ChangeEvent<HTMLInputElement>) => {
      model.firstName = e.target.value;
      setFirstNameValue(e.target.value);
  }

  const changeLastName = (e: React.ChangeEvent<HTMLInputElement>) => {
      model.lastName = e.target.value;
      setLastNameValue(e.target.value);
  }

  return (
  <React.Fragment>
   <div>
    <label htmlFor="firstName">FirstName:</label>
    <input name="firstName" value={firstNameValue} onChange={changeFirstName} />
   </div>
   <div>
    <label htmlFor="lastName">LastName:</label>
    <input name="lastName" value={lastNameValue} onChange={changeLastName}/>
   </div>
  </React.Fragment>);
};

Component2.tsx

export const Component2: React.FunctionComponent<IComponent> = ({ model }) => {
   const [passportValue, setPassportValue] = useState(model.passport);
   const [addressValue, setAddressValue] = useState(model.address);

  const changePassport = (e: React.ChangeEvent<HTMLInputElement>) => {
      model.passport = e.target.value;
      setPassportValue(e.target.value);
  }

  const changeAddress = (e: React.ChangeEvent<HTMLInputElement>) => {
      model.address = e.target.value;
      setAddressValue(e.target.value);
  }

  return (
  <React.Fragment>
   <div>
    <label htmlFor="passport">Passport:</label>
    <input name="passport" value={passportValue} onChange={changePassport} />
   </div>
   <div>
    <label htmlFor="address">Address:</label>
    <input name="address" value={addressValue} onChange={changeAddress}/>
   </div>
  </React.Fragment>);
};

Aucun commentaire:

Enregistrer un commentaire