Two-way-binding

I have a form with several fields that need to be pre-populated with values from the database on initial page load. When the user submits the form, the new values will be saved to the database. The latest values should always be displayed when the page is reloaded. If I'm not mistaken, I know I need to use createResource(...) to query the database. This returns a signal which I can use to populate the <input> and <select> HTML elements. The easiest way for me to populate a select element is by passing a value to its value property. continued in comments...
2 Replies
FatFreeButter
FatFreeButterOP3d ago
<input name="first_name" type="text" value={res().first_name}/>
<input name="first_name" type="text" value={res().first_name}/>
I need to do custom form validation upon form submit. There are two ways I can think of. 1) Bind a ref to each form element and get the value directly from the form element.
<input ref={firstNameEl} name="first_name" type="text" value={res().first_name}/>

const onSubmit = (e) => {
var isValid = true;

var firstName = firstNameEl.value;
isValid &= validate(firstName)

// validate other form elements...

if (!isValid) {
// prepare errors
return
}

// send request to server
}
<input ref={firstNameEl} name="first_name" type="text" value={res().first_name}/>

const onSubmit = (e) => {
var isValid = true;

var firstName = firstNameEl.value;
isValid &= validate(firstName)

// validate other form elements...

if (!isValid) {
// prepare errors
return
}

// send request to server
}
or 2) setup two-way-binding for each form element.
const [firstName, setFirstName] = createSignal("")

onMount(() => {
setFirstName(res().first_name);
});

<input name="first_name" type="text" value={firstName()} onInput={(e) => setFirstName(e.target.value)}/>

const onSubmit = (e) => {
var isValid = true;

isValid &= validate(firstName())

// validate other form elements...

if (!isValid) {
// prepare errors
return
}

// send request to server
}
const [firstName, setFirstName] = createSignal("")

onMount(() => {
setFirstName(res().first_name);
});

<input name="first_name" type="text" value={firstName()} onInput={(e) => setFirstName(e.target.value)}/>

const onSubmit = (e) => {
var isValid = true;

isValid &= validate(firstName())

// validate other form elements...

if (!isValid) {
// prepare errors
return
}

// send request to server
}
Which is the better approach? The first approach seems better to be because the second approach (two-way-binding) seems like it "might" caught unecessary re-renders and/or compute. When a user presses a key, setFirstName(...) is called and this results in firstName() being called for every keystroke. I know this is happening because I created a derived signal and observed it.
const derivedFirstName = () => {
console.log("here");
return firstName();
}
const derivedFirstName = () => {
console.log("here");
return firstName();
}
I often see people do two-way-binding the way I have written above, but I don't understand the purpose. I can understand if the firstName() signal is being used elsewhere (ex a submit function), but to use it like value={firstName()} seems like a waste of clock cycles.
Jose Rizal
Jose Rizal3d ago
@FatFreeButter could you please share me all codes? I will fix right away.

Did you find this page helpful?