Reputation: 373
I have handleClick
event which by clicking renderDetail
function must be run in {this.state.ShowInfo[i]}
div.I do it like below code:
I used callback but did not work.
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data: [],
ShowInfo: {},
}
}
render() {
const { data } = this.state
const renderInfo = data.map((item, i) => {
return (
<div class="item">
<div onClick={e => this.handleClick(e, item, i)}>
<span>Click</span>
</div>
<div>{this.state.ShowInfo[i]}</div>
</div>
)
})
return <div>{renderInfo}</div>
}
handleClick = (e, element, i) => {
fetch('/json.bc', {///I can see that the json.bc is loaded in network tab by result/////
method: 'POST',
})
.then(response => response.text())
.then(text => {
let Maindata = JSON.parse(text.replace(/\'/g, '"'))
this.setState(prevState => ({
ShowInfo: {
...prevState.ShowInfo, [i]: (Maindata, i) => {
console.log(Maindata)// console.log(Maindata) did not show anything.There is no result in this part////
let element = Maindata
let lenfamilies = element.families.length
console.log(lenfamilies)//// console.log(lenfamilies) did not show anything.There is no result in this part////
let indents = [];
for (let j = 0; j < lenfamilies; j++) {
let numF = i
let numS = j
let stingF = numF.toString()
let stingS = numS.toString()
index = stingF + stingS
indents.push(
<div>
<span
key={index}>
</span>
</div>
)
}
return (
indents
)
}
},
}))
}).catch(error => console.error(error))
}
}
ReactDOM.render(<App />, document.getElementById("Result"))
<div>{this.state.ShowInfo[i]}</div>
is empty by using callback.Have you any other way to call renderDetail
function in handleClick
event?
Edit:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data: [],
ShowInfo: {},
text: {}
}
}
render() {
const { data } = this.state
const renderInfo = data.map((item, i) => {
return (
<div class="item">
<div onClick={e => this.handleClick(e, item, i)}>
<span>Click</span>
</div>
<div>{this.state.ShowInfo[i]}</div>
</div>
)
})
return <div>{renderInfo}</div>
}
handleClick = (e, element, i) => {
fetch('/json.bc', {
method: 'POST',
},)
.then(response => response.text())
.then(text => {
let Maindata = JSON.parse(text.replace(/\'/g, '"'))
this.setState(prevState => ({
ShowInfo: { ...prevState.ShowInfo,[i]: this.renderDetail(Maindata, i)},
}))
}).catch(error => console.error(error))
}
renderDetail(element, i) {
let lenfamilies = element.families.length
let indents = []
let index = 0
for (let j = 0; j < lenfamilies; j++) {
let numF = i
let numS = j
let stingF = numF.toString()
let stingS = numS.toString()
index = stingF + stingS
indents.push(
<div>
<span
key={index}
onClick={e => this.handleText(e, element.families[j], index)}
>
Click
</span>
<span key={index}>
{this.state.text[index]}
</span>
</div>
)
}
return(
indents
)
}
handleText = (e, element, index) => {
this.setState(prevState => ({
text: { ...prevState.text, [index]: "test" }////In this part 'test' should be set in span but it is not been set
}))
}
}
Upvotes: 2
Views: 2349
Reputation: 104369
Its because {this.state.ShowInfo[i]}
is a function and to execute its body you need to call it by using ()
with function name.
Also dont forget to add a check before calling it because initial value of this.state.ShowInfo[i]
will be undefined and it will throw error with ()
.
Write it like this [notice ()
with ShowInfo[i]
]:
const renderInfo = data.map((item, i) => {
return (
<div class="item">
<div onClick={e => this.handleClick(e, item, i)}>
<span>Click</span>
</div>
{this.state.ShowInfo[i] && <div>{this.state.ShowInfo[i]()}</div>}
</div>
)
})
Suggestion: Instead of storing the function in state variable, better to store data only and write a generic method that will return the jsx part for each key.
Check this snippet:
function print() {
console.log('body of print method');
}
// it will print the function body
console.log(print);
// it will execute the function body
console.log(print());
Full Code:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data: [],
showInfoData: {},
text: {},
}
}
handleClick = (e, element, i) => {
fetch('/json.bc', {
method: 'POST',
})
.then(response => response.text())
.then(text => {
let Maindata = JSON.parse(text.replace(/\'/g, '"'));
this.setState(prevState => ({
showInfoData: {
...prevState.showInfoData,
[i]: Maindata,
}
}))
})
.catch(error => console.error(error))
}
showInfo(i) {
let element = this.state.showInfoData[i];
if(!element) return null;
let lenfamilies = element.families.length
let indents = [];
for (let j = 0; j < lenfamilies; j++) {
let numF = i
let numS = j
let stingF = numF.toString()
let stingS = numS.toString()
index = stingF + stingS
indents.push(
<div>
<span
key={index}
onClick={e => this.handleText(e, element.families[j], index)}
>
Click
</span>
<span key={index}>
{this.state.text[index]}
</span>
</div>
)
}
return (indents);
}
handleText = (e, text, i) => {
this.setState(prevState => ({
text: { ...prevState.text, [i]: text}
}))
}
render() {
const { data } = this.state
const renderInfo = data.map((item, i) => {
return (
<div class="item">
<div onClick={e => this.handleClick(e, item, i)}>
<span>Click</span>
</div>
<div>{this.showInfo(i)}</div>
</div>
)
})
return <div>{renderInfo}</div>
}
}
Upvotes: 1