I must be missing something very simple, but I can't figure out how to deal with having 2 value / onChange to pass to my component.
I tried changing the names, and that gets rid of errors and renders the app, but of course event.target.value does not work as if I change the second value to, for example to numval or something. event.target.numval doesn't recognize anything is happening.
Thank you so much in advance! And if this has been asked before I apologize, but I couldn't find it... which makes me think I'm overlooking a very simple solution.
return (
...
<PersonForm
onSubmit={addName}
value={newName}
onChange={handleName}
value={newNumber}
onChange={handleNumber}
/>
)
Here is the original code that worked fine before I tried to put the component into its own file:
return (
...
<form onSubmit={addName}>
<div>
name: <input value={newName} onChange={handleName} />
</div>
<div>
number: <input value={newNumber} onChange={handleNumber} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
your code sample is not clear but it seems you want to retrieve value from event.target object through event handler function triggered by onChange event on
an element. And you want to call event handler function available in a parent component from a child component.
You can try the following:
const App () => {
const [newNameValue, setName] = useState('');
const [newNumberValue, setNumber] = useState('');
const nameChangeHandler = (event) => {
setName(event.target.value);
};
const numberChangeHandler = (event) => {
setNumber(event.target.value);
};
const submitFormHandler = () => {
your code on form submit
};
return (
<PersonForm
submitForm={submitFormHandler}
newName={newNameValue}
handleName={nameChangeHandler}
newNumber={newNumberValue}
handleNumber={numberChangeHandler}
/>
);
}
const PersonForm (props) => {
return (
<form onSubmit={props.submitForm}>
<div>
name: <input value={props.newName} onChange={props.handleName} />
</div>
<div>
number: <input value={props.newNumber} onChange={props.handleNumber} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
);
}
onChange is a reserved attribute name which is available on few html elements
such as <input> and <select>. You should ideally not use it on other elements, like in your case custom html component <PersonForm>.
Since you're keeping form in separate component then you can trigger a function call received through attributes on props object.
You may call two different onChange event handler functions on two input elements.
I hope you got your answer, feel free to ask in case of any more doubts.
You may refer:
https://reactjs.org/docs/forms.html
Related
Using React Hook Form, when I want to collect data by sending register as props to child component to take input value from child component, it shows 'register is not a function' error.
How can I solve this?
const { register, formState: { errors }, handleSubmit } = useForm();
const onSubmit = (data) => console.log(data);
<form onSubmit={handleSubmit(onSubmit)}>
<fieldset>
<legend className='text-[#666666]' >Status</legend>
{
statusData.map(status => <CheckboxFilter register={register} key={status._id} status={status}/>)
}
</fieldset>
</form>
here child
//CheckboxFilter component
const CheckboxFilter = ({ status, register }) => {
return (
<>
<p className='text-[#858585] mt-2 text-[14px]' >
<label htmlFor={status?.name} className='cursor-pointer' >
<input {...register("checkBoxData")} type="checkbox" name="status" id={status?.name} value={"status?.name"} /> {status?.name}
</label>
</p>
</>
);
};
I created a sandbox here codesandbox and it works perfectly.
I took your code and only changed the CheckboxFilter component:
Removed the name property (register function returns the name of the input based in the string you pass to it as a parameter, you should not override it)
Removed the value property (that was making the value of the checkbox constant, because there wasn't onChange handler that was modifying it)
Changed ...register("checkBoxData") to ...register(checkBoxData${name}) so this way you can have every checkbox value individually in the form.
Anyway, if you want to have a different behaviour than what I have assumed, let me know and I will help.
-Ado
I’m wondering how can I change a children input value from main?
Basically I have a component that I’m sending a children, and in this component I want to be able to change the input value.
Here is my main:
<FooterOptions>
<input type="text"
onChange={event=>setState(event.target.value)}
value={state}
hidden/>
</FooterOptions>
And here is my component:
export function FooterOptions(props:{children: ReactNode}){
return(
<div>
{props.children}
</div>
)
}
The children prop is something that you can only render onto the page, so there's nothing you can do with it to change the value of the input.
Instead how I would think about this is that you want to provide a mechanism for FooterOptions to change the value of another component. Here it happens to also be rendered as its children, but it would work the same even if it was rendered someplace else.
const Parent = () => {
const updateInput = (val) => setState(val)
return (
<FooterOptions handleUpdate={updateInput}>
<input type="text"
onChange={event=>setState(event.target.value)}
value={state}
hidden/>
</FooterOptions>
)
}
export function FooterOptions(props:{children: ReactNode, handleUpdate}){
// Example handler
const handleClick = () => handleUpdate('updated inside FooterOptions')
return(
<div onClick={handleClick}>
{props.children}
</div>
)
}
If you'd like to add more details of how you are hoping to update, then I can add a better example 😀
Firstchild file:
const [qtd, setQtd] = useState(props.number);
function updateNumber(){
props.setNumber(qtd);
}
const handleChange = event => {
setQtd(event.target.value);
};
return(
<input type="number" name="integerTimes" className="integerTimes" placeholder='Insira aqui' id="qtd" onChange={handleChange}/>
<button id="submitTimes" onClick={updateNumber}>Enviar</button>
);
Parent Component:
const [number, setNumber] = useState(0);
if (number>0){
return (
<div id='main'>
<div>
<Firstchild setNumber={setNumber} number={number}/>
<SecondChild number={number}/>
</div>
</div>
);
}
the problem is, i need 'number' to pass to other child component, but apparently when the parent re-render i lose the update that i made in the first child component. How can i mantain the value of 'number' after changing in the child component?
You should have single source of truth especially when you are working with inputs because and inputs have there local state and you have to reference it to an external source in order to work properly.
reference your input's value to your parents state.
return(
<input type="number" value={props.number} />
);
Does anyone know how to make this code work in a React Functional Component?
onfocus="(this.type='date')" onblur="(this.type='text')"
I am trying to get placeholder text to appear prior to the user clicking on the input element. Then when clicked, the input will change to MM/DD/YYYY.
Trying to emulate something like this in my React project: https://stackoverflow.com/a/34565565/14677057
Would appreciate any help! Thank you!
Have a state variable for the type, then use it in what you render:
const Example = () => {
const [type, setType] = useState('text');
return (
<input
type={type}
onFocus={() => setType('date')}
onBlur={() => setType('text')}
/>
)
}
you can useRef for focusing. onBlur will work in camel case.
eg:
function CustomTextInput(props) {
// textInput must be declared here so the ref can refer to it
const textInput = useRef(null);
function handleClick() {
textInput.current.focus();
}
return (
<div>
<input
type="text"
ref={textInput} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
Handling events with react elements is syntactically different from DOM elements.
events are named using camelCase, rather than lowercase.
We need to pass a JSX function, rather than a string.
`
function HandleInputField(){
const onChange=()=>{//your code}
const onFocus=()=>{//your code}
const onBlur=()=>{//your code}
return <input onChange={} onFocus={} onBlur={}/>
}
`
I'm trying to pass mobx-react-form object as a prop to a function component I created. the problem is when I call my component like that
<NameEditor form={ newFolderForm }/>
I do get the form argument inside NameEditor component but it doesn't let me 'edit' the field .. its like the field isn't editable,
but when I call the component like that
{ NameEditor({ form: newFolderForm }) }
it works perfectly fine, what am I missing ? shouldn't the both ways be the same thing in function components ?
edit: here is how I fetch the form
const NameEditor = ({ form }) => (
<form onSubmit={ form.onSubmit }>
<input { ...form.$('name').bind() }/>
<p>{ form.$('name').error }</p>
<button>Save</button>
</form>
)
thanks
make sure you are using observer() on you're function component, from the code you showed there I think you missed this part.
const NameEditor = observer(({ form }) => (
<form onSubmit={ form.onSubmit }>
<input { ...form.$('name').bind() }/>
<p>{ form.$('name').error }</p>
<button>Save</button>
</form>
))
https://mobx.js.org/refguide/observer-component.html
read how it works with Stateless function components