Reputation: 740
I have make this TextInput component
export const TextInput = (props) => {
const { label } = props
return (
<div className="field text">
<input type="text" />
<label>{label}</label>
</div>
)
}
But at the call of this component, I would like to handleChange each input according to its name
handleChange = (e) => this.setState({ [e.target.name]: e.target.value })
<TextInput
label="Email"
name="email"
value={this.state.email}
onChange={this.handleChange}
/>
The problem is that my state and my method are not in the component.
I have to pass my method in props?
Upvotes: 2
Views: 1240
Reputation: 12174
The problem is that my state and my method are not in the component.
It's actually not a problem. You are doing the right thing.
It's what React calls as Lifting State Up.
So just use the props
in your child component.
export const TextInput = (props) => {
const { label } = props
return (
<div className="field text">
// use props
<input type="text"
onChange={props.onChange}
name={props.name}
value={props.value}
/>
<label>{label}</label>
</div>
)
}
Upvotes: 2
Reputation: 2280
So, you should create TextInput
like this:
export const TextInput = (props) => {
const {
name,
label,
value,
onChange,
disabled,
customClass,
...others
} = props
return (
<div className="field text">
<input
className={customClass}
name={name}
type="text"
disabled={disabled}
value={value}
onChange={e => onChange(e)} // I will return event here, not currenTarget.value
{...others}
/>
<label>{label}</label>
</div>
)
}
And then, you can use TextInput
as an input element
like this:
<TextInput
label="Email"
customClass="class-custom-input"
disabled={false}
name="email"
value={this.state.email}
onChange={this.handleChange} // at here you can received an `event`
onClick={...} // will be pass as ...others in TextInput
onBlur={...} // will be pass as ...others in TextInput
/>
Upvotes: 2
Reputation: 41
You can use the useRef hook and pass it to the TextInput component.
const emailRef = useRef(null)
handleChange = () => this.setState({ [emailRef.current.name]: emailRef.current.value })
<TextInput
label="Email"
name="email"
value={this.state.email}
onChange={this.handleChange}
ref={emailRef}
/>
Upvotes: 1
Reputation: 946
Try adding the onChange to the child component
export const TextInput = (props) => {
const { label } = props
return (
<div className="field text">
<input onChange={props.onChange} type="text" />
<label>{label}</label>
</div>
)
}
Upvotes: 1
Reputation: 10873
You need to enable the onChange handler on input
first:
export const TextInput = (props) => {
const { label } = props
return (
<div className="field text">
<input type="text" onChange={props.onChange}/>
<label>{label}</label>
</div>
)
}
Upvotes: 1