这是我的结构:
Main.js (Parent)
MainContainer.js
|
|_ Article.js
|
|__ Comments.js
现在,我想在评论组件(递归组件)上设置点击处理程序,并调度操作。
这是我关于comment.js的代码
class Comment extends Component {
deleteComment = (id) => {
this.props.handleDelete(id)
}
render() {
var comment = this.props.comment
return (
<div className={styles.commentsWrapper}>
<ul>
<li>
<div className={styles.commentsName}>
<a onClick={() => this.deleteComment(comment.id)} className={styles.commentsNameRight}>
</a>
</div>
<p>{comment.body}</p>
{comment.children.length > 0 && comment.children.map(function(child) {
return <Comment comment={child} key={child.id}/>
})}
</li>
</ul>
</div>
);
}
}
export default Comment;
和Article.js:
class Article extends Component {
handleDeleteComment = (id) => {
this.props.deleteComment(id)
}
render() {
return (
<article className={styles.articleItem}>
{this.props.comments.map(item =>
<Comment handleDelete={this.handleDeleteComment} comment={item} key={item.id}/>)}
</article>
);
}
}
export default Article;
还有Main.js
class Main extends Component {
deleteComment = (id) => {
this.props.deleteCommentRequest(id)
}
render() {
return (
<div className="">
<Header />
<section className="container">
<div>
{
!this.props.articles.loading && this.props.articles.articles? (
<div>
{this.props.articles.articles.map(item =>
<Article
bodytext={item.selftext}
key={item.id}
comments={item.finalComments}
deleteComment={this.deleteComment}
/>)}
</div>
) : (
<div className={styles.loading}> <Spin /> </div>
)
}
</div>
</section>
</div>
);
}
}
export default Main;
所以我在这里所做的是:将deleteComment
作为道具从主体传递到文章,再将handleDelete
从文章传递到评论。
不确定这是否是一个好方法吗?
预先感谢
答案 0 :(得分:2)
这种模式对于2到3个组件的深度没有问题,因为这是数据应该如何从子级流到祖先的方式。但是,如果您的应用程序变得越来越重,请考虑使用其他状态管理,例如redux,其中维护全局状态,任何组件都可以订阅它并调度操作。 here的更多内容。
或者,您也可以使用带有useContext
的React Hooks实现相同的功能,在其中您可以设置上下文,任何子组件都可以订阅它。示例:
const MyContext = React.createContext();
export default function App({ children }) {
const [items, setItems] = React.useState([]);
return (
<MyContext.Provider value={{ items, setItems }}>
{children}
</MyContext.Provider>
);
}
export { MyContext };
现在,只要位于App
组件的子级中的任何子级中,您都可以执行以下操作:
import {MyContext} from './filename';
function TodoItem() {
const { items, setItems } = React.useContext(MyContext);
return (
<div onClick={() => setItems(1)}>
</div>
);
}
答案 1 :(得分:1)
您可以使用上下文API将道具放在包装中,并可以从子组件轻松访问。
在youtube上有来自wesbos的精彩教程
class App extends Component {
render() {
return (
<MyProvider>
<div>
<p>I am the app</p>
<Family />
</div>
</MyProvider>
);
}
}
class MyProvider extends Component {
state = {
name: 'Wes',
age: 100,
cool: true
}
render() {
return (
<MyContext.Provider value={{
state: this.state,
growAYearOlder: () => this.setState({
age: this.state.age + 1
})
}}>
{this.props.children}
</MyContext.Provider>
)
}
}