How to pass onChange and props in a function - reactjs

I am trying to change the id of my input using props but I am also using an onChange event.
import React from "react";
function Toggle({ onChange }) {
return (
<>
<input type="checkbox" id="switch" onChange={onChange} />
<label htmlFor="switch"></label>
</>
);
}
export default Toggle;
I have tried like this:
import React from "react";
function Toggle({ onChange }, props) {
return (
<>
<input type="checkbox" id={props.id} onChange={onChange} />
<label htmlFor={props.id}>
</label>
</>
);
}
export default Toggle;
How do I do this?

You are destructuring props, you can obtain the other values like this:
{ onChange, ...props }
Your attempt
({ onChange }, props)
Is destructuring the first argument, and assuming that there is a second one called props
The ...props pattern from above is called a "rest" pattern, it also works with arrays

You can destructure id also.
function Toggle({ onChange, id }) {
return (
<>
<input type="checkbox" id={id} onChange={onChange} />
<label htmlFor={id}>
</label>
</>
);
}

Related

react-hook -form with SliderComponent input

Im new to react and I am trying to use a SliderComponent in a react Hook form but I cant seem able to fully understand how Controller works.
Here is my SliderComponent using react-input-slider:
export default function SliderComponent(props) {
const { axis, xmax, xmin, xstep, onChange } = props;;
return (
<div>
<Slider
axis={axis}
x={value.x}
xmax={xmax}
xmin={xmin}
xstep={xstep}
onChange={onChange}
/>
</div>
);
}
And here is my form:
export default function BiometricForm() {
const { handleSubmit, control } = useForm();
return (
<div className="registerForm_Container">
<form onSubmit={handleSubmit(onsubmit)}>
<Controller
control={control}
name="test"
render={({ props: { x, axis, xmax, xmin, xstep } }) => (
<SliderComponent
axis={"x"}
xmax={100}
xmin={1}
xstep={1}
value={x}
onChange={(e) => x.onChange(parseInt(e.target.value))}
/>
)}
/>
<button className="registerForm_Container_button" type="submit">
Register
</button>
</form>
</div>
);
}
I think it might be something to do with useState and that I am not able to reach useState of component. I have read that maybe its not necessary , any help? Thank you!
You are absolutely right, if you use RHF you don't need useState because RHF handles the form state for you. The important thing here is to pass an onChange handler to your <SliderComponent />, so that RHF can watch for value changes of your <SliderComponent /> and update the form state. You should also provide a defaultValue for the field, if you don't want it to be undefined if the user doesn't change the slider before submitting.
Also without the useState inside <SliderComponent />, you can also omit the <SliderComponent /> and just use <Slider />.
function BiometricForm() {
const { handleSubmit, control } = useForm();
const onSubmit = (data) => console.log(data);
return (
<div className="registerForm_Container">
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name="test"
defaultValue={50}
render={({ field: { value, onChange } }) => (
<Slider
axis={"x"}
xmax={100}
xmin={1}
xstep={1}
onChange={({ x }) => onChange(x)}
x={value}
/>
)}
/>
<input type="submit" />
</form>
</div>
);
}

react-hook-form access to validation rules in nested component

I'd like to access to the validation rules defined in react-hook-form's Resister in the nested component to dynamically display required indicator(*).
Is there a way to access from Nested component?
I don't want to repeat by passing as a prop.
<TextBox ref={register({ required: true })} label="Serial No" name="serialNo" />
const TextBox = React.forwardRef(({ label, name }, ref) => (
<>
<label htmlFor={name}>
{label} {***required*** && <span>*</span>}
</label>
<input type="text" name={name} id={name} ref={ref} />
</>
))
have a look at https://react-hook-form.com/api#useFormContext
import React from "react";
import { useForm, FormProvider, useFormContext } from "react-hook-form";
export default function App() {
const methods = useForm();
const onSubmit = data => console.log(data);
return (
<FormProvider {...methods} > // pass all methods into the context
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput />
<input type="submit" />
</form>
</FormProvider>
);
}
function NestedInput() {
const { register } = useFormContext(); // retrieve all hook methods
return <input name="test" ref={register} />;
}
which allow you to access all hook form methods in the nested component level.

handleChange is not a function , react

I am trying to pass a function to a react component but it say that it is not a function. I can console log the props and I have set it up, as far as i can tell, the same way I have always done. Please help, thanks!
EDIT: I get the same error when i try to test the onSubmit function, too
<div className="bookshelf">
<Searchbar
handleChange={onChange}
addInputClass={"searchbar_mobile_input"}
addBtnClass={"searchbar_mobile_btn"}
/>
<div className="bookshelf_heading_container">
<h2 className="bookshelf__heading">
Release the Kraken of Knowledge!
</h2>
</div>
import React, {Fragment} from "react";
const SearchBar = ({ addBtnClass, addInputClass, handleChange }) => {
console.log(handleChange)
return (
<Fragment>
<form className="search__form__input" onSubmit={() => handleSubmit(e)}>
<input
type="text"
placeholder="Search by Title/Author"
className={`searchbar__input ${addInputClass}`}
name="search"
onChange={(e) => handleChange(e)}
></input>
<button type="submit" className={`btn ${addBtnClass}`}>
Search
</button>
</form>
</Fragment>
);
};
export default SearchBar;
Here is an example that should help you. You should be able to take this simplified example and work out how to apply it to your example. I would've used your code but it was incomplete and no sandbox was provided.
import React from "react";
export default function AppLogic() {
const [readValue, writeValue] = React.useState("");
const handleChange = (e) => writeValue(e.target.value);
const handleSubmit = (e) => {
e.preventDefault();
alert("Submitted");
};
const props = { readValue, handleChange, handleSubmit };
return <AppView {...props} />;
}
function AppView({ handleSubmit, handleChange, readValue }) {
return (
<div className="App">
<h1>Name</h1>
<form onSubmit={handleSubmit}>
<input onChange={handleChange} value={readValue} />
<input type="submit" />
</form>
<p>{readValue}</p>
</div>
);
}

Component doesn't trigger functions

render() {
const { newRepo, loading, repositories } = this.state;
return (
<Container>
<RepoForm onSubmit={this.handleSubmit}>
<FormInput onChange={this.handleInputChange} value={newRepo} />
<SubmitButton loading={loading} />
</RepoForm>
<RepoList repositories={repositories} />
</Container>
);
export default function FormInput() {
return <Container type="text" placeholder="Adicionar repositório" />;
}
My code doesn't activate the function onChange when I change the input. The two codes are in separate files. Why is this happening?
We don't have the detailed implementation of the Container component. Usually, you will need to pass down the even handler from parent to child as a prop.
// get the reference of the onChange prop
export default function FormInput({ onChange }) {
// connect onChange function with the actual component that handles input
return <Container type="text" onChange={onChange} placeholder="Adicionar repositório" />;
}
I hope it helps.

How to set state for text box in functional component

I am working on React JS. I have one text-box component and I want to show some default value in it. After that, the user should be allowed to change the value. Now I am unable to change the value. The text box is behaving like read-only. Below is my code
const EditStyleFormComponent = ({
submitting,
invalid,
}) => (
<form className={className} onSubmit={handleSubmit}>
<h2>LSPL (Low Stock Presentation Level)</h2>
<Line />
<InputGroup>
<TextFieldWithValidation name="lsplMan" label="LSPL Manual" input={{ onChnage:'', value: 'Current' }} />
</InputGroup>
</form>
);
Below is my TextFieldWithValidation code.
export const TextFieldWithValidationComponent = ({
meta,
input,
noStyles,
...otherProps
}) => (
<TextField
state={noStyles ? textFieldStates.DEFAULT : getState(meta)}
errorMessage={meta.touched ? meta.error : null}
{...input}
{...otherProps}
/>
);
Below is my TextField code.
const TextField = ({
className,
label,
description,
state,
errorMessage,
isEditable,
spaceAtBottom, // Not used, but we don't want it in otherProps
...otherProps
}) => {
const inputId = _.uniqueId();
return (
<div className={className}>
{label &&
<label htmlFor={inputId}>{label}</label>
}
<div className="input-group" id={isEditable ? 'editable' : 'readonly'}>
<input
id={inputId}
readOnly={!isEditable}
{...otherProps}
/>
{getStatusIcon(state)}
{errorMessage &&
<Error>{errorMessage}</Error>
}
{description &&
<Description>{description}</Description>
}
</div>
</div>
);
};
Can someone help me to fix this issue? Any help would be appreciated. Thanks
You can use State Hook for manage state in functional component.
Example :
const Message = () => {
const [message, setMessage] = useState( '' );
return (
<div>
<input
type="text"
value={message}
placeholder="Enter a message"
onChange={e => setMessage(e.target.value)}
/>
<p>
<strong>{message}</strong>
</p>
</div>
);
};
Yu defined onChange as empty string in EditStyleFormComponent component. So on any change input component just do nothing.
onChange should be some function that will update value.
If you want to use functional components there are two possible solutions:
Lift state up to parent component of EditStyleFormComponent (in case parent is class based component)
Use React Hooks like so (just example!)
const EditStyleFormComponent = ({
submitting,
invalid,
}) => {
const [inputValue, setInputValue] = useState ('Current'); // default value goes here
return <form className={className} onSubmit={handleSubmit}>
<h2>LSPL (Low Stock Presentation Level)</h2>
<Line />
<InputGroup>
<TextFieldWithValidation name="lsplMan" label="LSPL Manual" input={{ onChnage: (e) => { setInputValue(e.target.value); }, value: inputValue }} />
</InputGroup>
</form>
};

Resources