Reputation: 119
I'm sitting with this for a while and wondering if there is any possibility of passing the state from parent to child in this case?
I need this id to give input and label an unique id couse this component is used multiple times.
Thanks for any advice.
Parent:
<FileUpload key={el.id} parentCallback={this.callback(el.id)} id={el.id}/>
Child:
import React, { Fragment, useState } from 'react';
import Message from './Message';
import Progress from './Progress';
import axios from 'axios';
const FileUpload = ({ parentCallback }) => {
return (
<Fragment>
<form className="image__uploadForm" onSubmit={onSubmit}>
{this.props.id} // Causes error props undef
<div className='image__upload'>
<input
type='file'
className='input__uploadFile'
id='uploadFile'
accept="image/*"
onChange={onChange}
/>
<label className='input__uploadFile--label' htmlFor='uploadFile'>
{filename}
</label>
{!file ? (
null
) :
<input
type='submit'
value='Upload'
/>
}
</div>
</form>
</Fragment>
);
};
export default FileUpload;
Upvotes: 0
Views: 602
Reputation: 1433
You can not pass your callback like this parentCallback={this.callback(el.id)}
because it will be executed instantly by render.
You could try to pass in an error function like parentCallback={() => this.callback(el.id)}
and call it in the submit function
Id
is undefined because Id
is a key word and will be not passed
Parent:
<FileUpload key={el.id} parentCallback={() => this.callback(el.id)} {...el}/>
Child:
import React, { Fragment, useState } from 'react';
import Message from './Message';
import Progress from './Progress';
import axios from 'axios';
const FileUpload = ({ parentCallback, id }) => {
const onSubmit = () => {
return parentCallback()
}
return (
<Fragment>
<form className="image__uploadForm" onSubmit={onSubmit}>
{id}
<div className='image__upload'>
<input
type='file'
className='input__uploadFile'
id='uploadFile'
accept="image/*"
onChange={onChange}
/>
<label className='input__uploadFile--label' htmlFor='uploadFile'>
{filename}
</label>
{file && <input type='submit' value='Upload'/>} //Tip: If you work with && you do not need to return null
</div>
</form>
</Fragment>
);
};
export default FileUpload;
Otherwise you can pass your function like:
Parent:
<FileUpload key={el.id} parentCallback={this.callback} {...el}/>
Child:
....
const FileUpload = ({ parentCallback, id }) => {
const onSubmit = () => {
return parentCallback(id)
}
return (....)
}
Upvotes: 0
Reputation: 14365
As @ajobi said, this
will not be defined in a functional component using the arrow syntax.
You can solve this three ways:
1. Use the rest
syntax to gather all props except parentCallback
into a variable called props
:
const FileUpload = ({ parentCallback, ...props }) => {
...
{props.id}
2. Spread all props into their own variables:
const FileUpload = ({ parentCallback, id }) => {
...
{id}
3. Spread none of the variables and use the props
object when using all props in your component:
const FileUpload = (props) => {
...
{props.id}
...
props.parentCallback
Upvotes: 2