admin管理员组文章数量:1299980
I have the following ReactJS ponent:
articles_list.jsx
import React from 'react';
import marked from 'marked';
import './articles_list.css';
export default class ArticlesList extends React.Component {
constructor(props) {
super(props);
this.state = {
articles: null
}
}
ponentWillMount() {
fetch('/articles_all')
.then(res => res.json())
.then(json => {
this.setState({
articles: json.articles
});
});
}
handleClick(e) {
e.preventDefault();
var elem = e.target;
var file = elem.getAttribute('data-file').split('.')[0];
fetch('/article/'+file, {
headers: {
'Accept': 'text/markdown'
}
})
.then(res => res.text())
.then(txt => marked(txt))
.then(html => document.getElementById('article-text').innerHTML = html)
}
render() {
var teste = []
if (this.state.articles === null) {
teste.push(<div id="no-articles" key="1">No articles</div>)
} else {
{this.state.articles.forEach( function(element, index) {
teste.push(<div onClick={this.handleClick} data-file={element.file} className="articles-menu-item" key={index.toString()}>{element.title}</div>);
}.bind(this))}
}
return(
<div className="articles-list">
<div className="articles-list-title">
ARTICLES
</div>
<div id="menu-body" className="menu-body">{teste}</div>
</div>
);
}
}
As you may see, it fetches as list of articles and creates links. When these links are clicked the corresponding article is load in a certain area of the page.
The code is working perfectly, but now I need to load a certain article before any of the links to be clicked. Then I decided to break the code inside handleClick
like this:
loadArticle(file) {
fetch('/article/'+file, {
headers: {
'Accept': 'text/markdown'
}
})
.then(res => res.text())
.then(txt => marked(txt))
.then(html => document.getElementById('article-text').innerHTML = html)
}
handleClick(e) {
e.preventDefault();
var elem = e.target;
var file = elem.getAttribute('data-file').split('.')[0];
loadArticle(file);
}
My idea with this is to invoke loadArticle
inside render
to load an specific article when the ponent loads, like this:
return(
<div className="articles-list">
<div className="articles-list-title">
ARTICLES
</div>
<div id="menu-body" className="menu-body">{teste}{this.loadArticle('my_specific_article')}</div>
</div>
);
It works and now my_specific_article
loads correctly when I navigate to the page. But...
But now when I click the links, that were working fine before, I got an error
Uncaught ReferenceError: loadArticle is not defined
And if I do
handleClick(e) {
e.preventDefault();
var elem = e.target;
var file = elem.getAttribute('data-file').split('.')[0];
this.loadArticle(file);
}
using this
, then I get
Uncaught TypeError: Cannot read property 'loadArticle' of null
How should I deal with this? I know it is a matter of context but, being new to ReactJS, I really don't know how to proceed.
EDIT
This is not a duplicate of this question, as it was marked. The reason is simple. In the mentioned question the function to bind is a event handler and in my problem a function being called by another. In fact, my event handler (similar to the other question) was working fine without the bind
, then we are not talking about the same thing.
I have the following ReactJS ponent:
articles_list.jsx
import React from 'react';
import marked from 'marked';
import './articles_list.css';
export default class ArticlesList extends React.Component {
constructor(props) {
super(props);
this.state = {
articles: null
}
}
ponentWillMount() {
fetch('/articles_all')
.then(res => res.json())
.then(json => {
this.setState({
articles: json.articles
});
});
}
handleClick(e) {
e.preventDefault();
var elem = e.target;
var file = elem.getAttribute('data-file').split('.')[0];
fetch('/article/'+file, {
headers: {
'Accept': 'text/markdown'
}
})
.then(res => res.text())
.then(txt => marked(txt))
.then(html => document.getElementById('article-text').innerHTML = html)
}
render() {
var teste = []
if (this.state.articles === null) {
teste.push(<div id="no-articles" key="1">No articles</div>)
} else {
{this.state.articles.forEach( function(element, index) {
teste.push(<div onClick={this.handleClick} data-file={element.file} className="articles-menu-item" key={index.toString()}>{element.title}</div>);
}.bind(this))}
}
return(
<div className="articles-list">
<div className="articles-list-title">
ARTICLES
</div>
<div id="menu-body" className="menu-body">{teste}</div>
</div>
);
}
}
As you may see, it fetches as list of articles and creates links. When these links are clicked the corresponding article is load in a certain area of the page.
The code is working perfectly, but now I need to load a certain article before any of the links to be clicked. Then I decided to break the code inside handleClick
like this:
loadArticle(file) {
fetch('/article/'+file, {
headers: {
'Accept': 'text/markdown'
}
})
.then(res => res.text())
.then(txt => marked(txt))
.then(html => document.getElementById('article-text').innerHTML = html)
}
handleClick(e) {
e.preventDefault();
var elem = e.target;
var file = elem.getAttribute('data-file').split('.')[0];
loadArticle(file);
}
My idea with this is to invoke loadArticle
inside render
to load an specific article when the ponent loads, like this:
return(
<div className="articles-list">
<div className="articles-list-title">
ARTICLES
</div>
<div id="menu-body" className="menu-body">{teste}{this.loadArticle('my_specific_article')}</div>
</div>
);
It works and now my_specific_article
loads correctly when I navigate to the page. But...
But now when I click the links, that were working fine before, I got an error
Uncaught ReferenceError: loadArticle is not defined
And if I do
handleClick(e) {
e.preventDefault();
var elem = e.target;
var file = elem.getAttribute('data-file').split('.')[0];
this.loadArticle(file);
}
using this
, then I get
Uncaught TypeError: Cannot read property 'loadArticle' of null
How should I deal with this? I know it is a matter of context but, being new to ReactJS, I really don't know how to proceed.
EDIT
This is not a duplicate of this question, as it was marked. The reason is simple. In the mentioned question the function to bind is a event handler and in my problem a function being called by another. In fact, my event handler (similar to the other question) was working fine without the bind
, then we are not talking about the same thing.
-
binding issue, write this line in the
constructor
:this.handleClick = this.handleClick.bind(this)
or convert that function into arrow, like this:handleClick = (e) => {
– Mayank Shukla Commented Jun 7, 2017 at 7:52 - Possible duplicate of Reactjs ponent does not re-render after setState – Shubham Khatri Commented Jun 7, 2017 at 8:12
-
The issue is the same,
this
is not referering to the correct context, there are a lots of questions having the same issue, The first I found, I added – Shubham Khatri Commented Jun 7, 2017 at 8:23 - I understand your point, thanks @ShubhamKhatri. – Edvaldo Silva de Almeida Jr Commented Jun 7, 2017 at 8:30
- No Problem :), Any ways glad your problem was solved – Shubham Khatri Commented Jun 7, 2017 at 8:31
1 Answer
Reset to default 5You must bind your custom functions in the constructor. Modify your constructor like this.
constructor(props) {
super(props);
this.state = {
articles: null
}
this.handleClick = this.handleClick.bind(this);
this.loadArticle = this.loadArticle.bind(this);
}
Now everywhere you should call this function as this.handleClick
& this.loadMore
.
You can read about other binding patterns here. The one I've mentioned is number 4.
That is the preferred way in facebook docs as well.
本文标签: javascriptCalling a function from another in ReactJsStack Overflow
版权声明:本文标题:javascript - Calling a function from another in ReactJs - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741641357a2389937.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论