Skip to content

Instantly share code, notes, and snippets.

@casdidier
Last active May 17, 2020 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save casdidier/4739d462c676704279b8d79282cb0224 to your computer and use it in GitHub Desktop.
Save casdidier/4739d462c676704279b8d79282cb0224 to your computer and use it in GitHub Desktop.
the fields are not updated after using useEffect
import { useState } from 'react';
const RoomForm = (initialValues, callback) => {
const [inputs, setInputs] = useState(initialValues);
const handleSubmit = (event) => {
// If we are submitting from a modal, we don't want the RoomSearch page to reload, due to the default submit behaviour.
if (event && event.target && event.target.name === 'MODAL_FORM') event.preventDefault();
// Then call back
callback();
}
const handleInputChange = (event) => {
event.persist();
setInputs(inputs => ({ ...inputs, [event.target.name]: event.target.value }));
}
return {
handleSubmit,
handleInputChange,
inputs
};
}
export default RoomForm;
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import RoomForm from '../../hooks/RoomHooks';
const RoomUpdate = ({ update, formName, saveButton, roomId, children }) => {
const { inputs, handleInputChange, handleSubmit } = RoomForm(
{
nombre_de_lits: '',
logement: 'Bengalow',
lit_simple: '',
lit_double: ''
},
() => update(inputs)
);
useEffect(() => {
const url = `http://localhost:8000/room/${roomId}`;
// Update the document title using the browser API
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then((response) => response.json())
.then((jsonResponse) => {
return jsonResponse;
})
.then((data) => {
// console.log('Success:', data);
const { nombre_de_lits, logement, lit_simple, lit_double } = data;
inputs.nombre_de_lits = nombre_de_lits;
inputs.logement = logement;
inputs.lit_simple = lit_simple;
inputs.lit_double = lit_double;
console.log('this is the inputs', inputs);
})
.catch((error) => {
console.error('Error:', error);
});
console.log('mounted');
});
return (
<div className="section is-fullheight">
<h2>ROOM</h2>
<div className="container">
<div className="column is-4 is-offset-4">
<div className="box">
<form onSubmit={handleSubmit} autoComplete="off" name={formName}>
<div className="field">
<label className="label has-text-centered">
Nombre de couchages
</label>
<div className="control">
<input
className="input"
type="number"
name="nombre_de_lits"
onChange={handleInputChange}
value={inputs.nombre_de_lits}
required
/>
</div>
</div>
<div className="field">
<label className="label has-text-centered">
Type de logement
</label>
<div className="control">
<input
className="input"
type="text"
name="logement"
onChange={handleInputChange}
value={inputs.logement}
required
/>
</div>
</div>
<div className="field">
<label className="label has-text-centered">
Nombre de lits simples
</label>
<div className="control">
<input
className="input"
type="number"
name="lit_simple"
onChange={handleInputChange}
value={inputs.lit_simple}
required
/>
</div>
</div>
<div className="field">
<label className="label has-text-centered">
Nombre de lits double
</label>
<div className="control">
<input
className="input"
type="number"
name="lit_double"
onChange={handleInputChange}
value={inputs.lit_double}
required
/>
</div>
</div>
<button
className="button is-block is-fullwidth is-success"
type="submit"
style={saveButton}
>
Créer le logement
</button>
{children}
</form>
</div>
</div>
</div>
</div>
);
};
const mapStateToProps = (state, ownProps) => {
return {};
};
const mapDispatchToProps = (dispatch, ownProps) => {
const url = 'http://localhost:8000/room/update';
return {
updateRoom: (inputs) => {
const data = { ...inputs };
fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then((response) => response.json())
.then((jsonResponse) => {
if (ownProps.displayModal2) ownProps.displayModal2();
return jsonResponse;
})
.then((data) => {
dispatch({ type: 'UPDATE_ROOM', data });
})
.catch((error) => {
console.error('Error:', error);
});
}
};
};
export default connect(mapStateToProps, mapDispatchToProps)(RoomUpdate);
@casdidier
Copy link
Author

casdidier commented May 17, 2020

  1. store some default form values in REACT STATE
  2. useEffect with zero dependencies to request data from API
    2.b use setXState to update the state
  3. component rerenders
    Okay
    First of all, this seems like an awful practise to use a hook outside of a component, especially for something so simple
    Even still, you are not updating the state
    Did you write this code?
    You have not called handleInputChange to reflect a change in the state. Instead, you are updating state directly
    best way to do it :
    const [formData, setFormData] = useState(RoomForm(/** default values **/));
type FormState = {
  username: string,
  password: string,
  otherThing: number
}

const SomeComponent = () => {
  const [formState, setFormState] = useState<FormState>(
    username: '',
    password: '',
    otherThing: 0
  );

  useEffect(() => getFormStateFromAPI().then(setFormState), []);
  return (...);
}

The quick and dirty solution to your problem is to manually call handleInputChange at the end of your useEffect
But like I say, this is bad practise, and you should look up some tutorials to implement something more maintainable

That's fine, and certainly not a bad thing that you tried, but you are externalizing the wrong logic
The logic of performing the API request and modelling the result as an object should be externalized to a class
For example a RoomFormService that performs the API request, uses the axios json method, and collects the fields you need as a type

useEffect(() => {
  RoomFormService.getRoom(roomId).then(room => {
    setFormState(
      nombre_de_lits: room.de_lits
    );
  });
}, []);

Managing the validation + updating the values is also very simple.

const [formState, setFormState] = useState<FormState>(/* default values */);
return (
  <input value={formState.someValue} onChange={newValue => setFormState({...formState, someValue: newValue})} />
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment