I'm building a react application and I'm encountering the following problem:
I have a blog. The blog is implemented with a class component like this:
class Blog extends Component {
constructor() {
super();
this.state = {
blogPosts: [],
newPost: {
title: null,
body: null
},
editPostId: null,
accessToken: null,
file: null,
currentPagePosts: [],
pageSize: 5
};
this.changeHandler = this.changeHandler.bind(this);
this.submitHandler = this.submitHandler.bind(this);
this.clearForm = this.clearForm.bind(this);
this.readMoreClicked.bind(this);
this.postTitleRef = React.createRef();
this.postBodyRef = React.createRef();
this.selectedFileRef = React.createRef();
}
...
readMoreClicked(postId) {
const post = this.state.blogPosts.find(p => p.id === postId);
post.collapsed = false;
this.setState({blogPosts: this.state.blogPosts});
}
createTable() {
return this.state.blogPosts.length
? <Table
posts={this.state.currentPagePosts}
isLoggedIn={!!this.state.accessToken}
editPost={this.editPost}
readMoreClicked={this.readMoreClicked} />
: null;
}
...
}
The component basically maintains a table of blog posts that looks like this:
The problem is the read more... links. In the code snippet above, I pass the handler for the read more link to the blog table in createTable(). The Table component is a functional component. It looks like this:
function Table(props) {
...
return (
...
<div className="read-more-link-container">
<span className="read-more-link" onClick={() => props.readMoreClicked(id)}>
Read more...
</span>
</div>
...
)
}
When someone clicks the read more link, it calls the readMoreClicked() method in the blog component (also in the snippet above). But in the readMoreClicked() method, it tells me the state is not defined:
This makes me wonder if the state of the blog component won't necessarily come into scope just because you call a method within it from a functional component. <-- Is this the problem? Or is there something else going on?
Thanks.
Try adding a piece of code
super(props) {
....
this.readMoreClicked.bind(this);
....
this.state = {};
}
and define your state on super constructors
I implemented this hack to solve the problem, but it is a hack and I'm still hoping someone can offer a better solution:
First, I added a 'that' prop to the Table component:
createTable() {
return this.state.blogPosts.length
? <Table
posts={this.state.currentPagePosts}
isLoggedIn={!!this.state.accessToken}
editPost={this.editPost}
readMoreClicked={this.readMoreClicked}
that={this} /> // <------------- HERE
: null;
}
Second, I pass prop.that to readMoreClicked() from the Table component like this:
<div className="read-more-link-container">
<span className="read-more-link" onClick={() => props.readMoreClicked(id, props.that)}>
Read more...
</span>
</div>
This works. The blog component's state is now available in readMoreClicked() by referencing that.state.
But this is obviously a hack. Does anybody know a better solution?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.