Reputation: 187
I want to setstate of PageSearchByExcel's class but I know that (this) is no longer to PageSearchByExcel.
Have you some way to set state to a totalMatchSample variable.
I bring this code from ant-design Official web. https://ant.design/components/upload/
I'm very new to react.
Help me, please.
Or If you have another way that is better than this way please give it to me.
import ...
const props = {
name: 'file',
multiple: true,
action: API_URL + '/api/search/excelfile',
onChange(info) {
const status = info.file.status;
const data = new FormData()
data.append('file', info.file.originFileObj, info.file.name)
Axios.post(props.action, data)
.then((Response) => {
this.setState({
totalMatchSample: info.file.response.length
})
})
},
};
export default class PageSearchByExcel extends React.Component {
constructor(props) {
super(props)
this.state = {
totalSample: 0,
totalMatchSample: 0
}
}
render() {
return (
<div>
<Dragger {...props}>
<p className="ant-upload-drag-icon">
<Icon type="inbox" />
</p>
<p className="ant-upload-text">Click or drag file to this area to upload</p>
<p className="ant-upload-hint">Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files</p>
</Dragger>
<div>
<p>
{this.state.totalMatchSample} matched samples from
{this.state.totalSample} samples
</p>
<br />
</div>
</div>
)
}
}
Upvotes: 1
Views: 5188
Reputation: 3774
Since you're declaring props
outside the PageSearchByExcel
component the this
refers to props object itself and not the component. You can define the onChange
method on the component and pass it down as a prop to Dragger
which then will be correctly bound to PageSearchByExcel
.
import ...
const props = {
name: 'file',
multiple: true,
action: API_URL + '/api/search/excelfile',
};
export default class PageSearchByExcel extends React.Component {
constructor(props) {
super(props)
this.state = {
totalSample: 0,
totalMatchSample: 0
}
}
// Define onChange here
onChange = (info) => {
const status = info.file.status;
const data = new FormData()
data.append('file', info.file.originFileObj, info.file.name)
Axios.post(props.action, data)
.then((Response) => {
this.setState({
totalMatchSample: info.file.response.length
})
})
}
render() {
return (
<div>
<Dragger {...props} onChange={this.onChange}>
<p className="ant-upload-drag-icon">
<Icon type="inbox" />
</p>
<p className="ant-upload-text">Click or drag file to this area to upload</p>
<p className="ant-upload-hint">Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files</p>
</Dragger>
<div>
<p>
{this.state.totalMatchSample} matched samples from
{this.state.totalSample} samples
</p>
<br />
</div>
</div>
)
}
}
Hope this helps !
Upvotes: 2
Reputation: 611
@sun, based on what you posted, i will assume that you have some sort of props being passed to PageSearchByExcel component.
having said that, that props object, its an anti-pattern, you really want to pass each key in that props object to PageSearchByExcel down via the props system.
ex:
Class ParentComponent ...
...some code
render () {
..someJSX
<PageSearchByExcel name='file' multiple={true} />
}
this will basically setup your props inside PageSearchByExcel
now thats out of the way, let's talk about setState({}) and loading resources
in your PageSearchByExcel Component, you would have something like this
export default class PageSearchByExcel extends React.Component {
constructor(props) {
super(props)
this.state = {
totalSample: 0,
totalMatchSample: 0
}
}
// define your axios call inside your component class NOT OUTSIDE
loadResource = () => {
// ....yourAxiosCodeHere
}
// You then set the state at the first load of the component
componentDidMount () {
this.loadResource()
}
render() {
return (
<div>
<Dragger {...this.props}>
<p className="ant-upload-drag-icon">
<Icon type="inbox" />
</p>
<p className="ant-upload-text">Click or drag file to this area to upload</p>
<p className="ant-upload-hint">Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files</p>
</Dragger>
<div>
<p>
{this.state.totalMatchSample} matched samples from
{this.state.totalSample} samples
</p>
<br />
</div>
</div>
)
}
}
TAKEAWAY::
1.) define your class methods inside the class itself in order the properly reference 'this'
2.) make sure you pass the props down from the parent component down to your PageSearchByExcel
3.) make sure you load your resource using the react life cycle method
This should get you going.
Upvotes: 1