JustMe
JustMe

Reputation: 31

React get inputs value without binding to a state

I have a Database table containing every needed info while uploading a file, so the inputs have to change every time according to the file type chosen so I cannot bind them to a state or use Ref.

Is there any way to get every input's value?

EDIT:

small code example

const [inputs, loading] = useFetch(url);

return (
<>
   {inputs.map((input) =>
      <Fragment key={input.key}>
         <div className="row">
           <label>{input.label}</label>
           <input type="text" placeholder={input.label} maxLength={input.maxLength} required={input.required} />
         </div>
      </Fragment>
    )}
<>
);

Upvotes: 0

Views: 742

Answers (1)

David
David

Reputation: 219016

The fact that you're fetching data from a server in no way means that you can't use state. Fetching data from a server and putting it in state is a very common use case.

Take a look at the Managed State example for useFetch. Use that to load your data:

const [inputs, setInputs] = useState([]);
const { get, post, response, loading, error } = useFetch(baseUrl);

useEffect(() => {
  loadInitialInputs();
}, []);

const loadInitialInputs = async () => {
  const initialInputs = await get(relativeUrl);
  if (response.ok) {
    setTodos(initialInputs);
  }
};

(Note how url has been split into baseUrl and relativeUrl.)

Now your inputs is in state. And you can update that state with setInputs. For example:

<input
  type="text"
  placeholder={input.label}
  maxLength={input.maxLength}
  required={input.required}
  value={input.value}
  onChange={e => handleChange(e, input.key)}
/>

(If input.value is initially undefined then this could produce warnings about changing from an uncontrolled component to a controlled component. You can modify loadInitialInputs to add that property, for example: setTodos(initialInputs.map(i => ({...i, value: ''})));)

And your handleChange function might look like this:

const handleChange = (e, key) => {
  const existingInput = inputs.find(i => i.key === key);
  if (existingInput) {
    const updatedInput = { ...existingInput, value: e.target.value };
    setInputs([...inputs.map(i => {
      if (i.key === key) {
        return updatedInput;
      } else {
        return i;
      }
    })]);
  }
};

There are various other ways to structure it, but the overall idea is that updating the "input" simply involves finding the target object in the array (based on the key value) and updating state to a new array with an updated version of that object.


Overall the point here is that you can use state with data fetched from the server. All you have to do is... put that data in state.


Aside... If your useFetch is not the one I found via Google, that's okay. The same concept still applies, however you are fetching data from the server. Just put that data in state and then you can use state.

Upvotes: 1

Related Questions