Reputation: 3054
I have 2 <input type="text">
elements. What users type in input 1 will be the default value of input 2. The value of input 2 will be used for other tasks. The tasks should run right when the dialog is opened.
My island code:
import { useState } from "preact/hooks";
export default function Test() {
const [value1, setValue1] = useState("");
const [value2, setValue2] = useState("");
console.log("value1:", value1)
console.log("value2:", value2)
return (
<div>
<input type="text" autoFocus
value={value1}
onInput={e => setValue1(e.target.value)}
/>
<input type="text"
value={value2 || value1}
onInput={e => setValue2(e.target.value)}
/>
<br />
Value2: {value2}
</div>
);
}
I expect value2
to show right when input 1 has value. However it doesn't. Only when there is a modification on the value of input 2 that value2
is set. Why is it the case? How to fix this?
What I'm actually doing: I have a search bar to search for saved URLs, and if users want to create new data from new URL, they can paste the URL to the search bar, then a modal will show. Inside the modal there will be a form for them to add more metadata. The first field is the URL, which is what they just paste. The other fields are populated automatically, but they can edit manually. Currently they have to make a dumb edit in the URL field to trigger the task.
Note that in Preact, onInput
is used instead of onChange
.
Upvotes: 0
Views: 45
Reputation: 2967
There's usually better patterns available, but without a very specific reproduction, here's one way you could do it:
import { useReducer } from 'preact/hooks';
const initialState = { value1: '', value2: '' };
const reducer = (state, action) => {
switch (action.input) {
case 1: return { value1: action.value, value2: action.value };
case 2: return { ...state, value2: action.value };
default: throw new Error('Unexpected action');
}
};
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<input value={state.value1} onInput={(e) => dispatch({ input: 1, value: e.currentTarget.value })} />
<input value={state.value2} onInput={(e) => dispatch({ input: 2, value: e.currentTarget.value })} />
<p>Value1: {state.value1}</p>
<p>Value2: {state.value2}</p>
</div>
);
}
render(<App />, document.getElementById('app'));
Upvotes: 0