I'm having hard time introducing UrlInput
component in React. The main idea is to get props, like url
and its setter (from parent) and split it internally into 3 UrlInput
state values, e.g. protocol
, host
and port
. UrlInput
should use 3 form fields and change a single url
in parent.
Simplified version:
export const UrlInput = ({ url, parentSetter }) => {
const [fields, setFields] = useState({ protocol: "", host: "", port: 0 });
useEffect(() => {
const urlRegex = /(https?):\/\/([a-z]+):([0-9]{4,6})/;
const [, protocol, host, port] = url.match(urlRegex);
setFields({ protocol, host, port });
}, [url]);
const onChange = e => {
setFields({ ...fields, [e.target.name]: e.target.value });
parentSetter(`${fields.protocol}://${fields.host}:${fields.port}`);
};
return (
<>
<input type="text" name="protocol" value={fields.protocol} onChange={onChange} />
://
<input type="text" name="host" value={fields.host} onChange={onChange} />
:
<input type="number" name="port" value={fields.port} onChange={onChange} />
<p>{JSON.stringify(fields)}</p>
</>
);
};
function App({ url: initialUrl }) {
const [url, setUrl] = useState(initialUrl);
const [age, setAge] = useState(0);
return (
<>
<input type="number" name="age" value={age} onChange={e => setAge(e.target.value)} />
<br />
<UrlInput url={url} parentSetter={setUrl} />
<p>{JSON.stringify({ url, age })}</p>
</>
);
}
Current behavior:
protocol
: UrlInput
state changes, parent's state does nothost
: Parent synchronizes protocol
with UrlInput
and UrlInput
changes have no effectand so on. You can verify the behavior here.
I want to have a simple API - just url
and setter
, but maybe it's not how it should be done?
use this code:
const onChange = e => {
const data = { ...fields, [e.target.name]: e.target.value };
setFields(data);
parentSetter(`${data.protocol}://${data.host}:${data.port}`);
};