我一直试图找到一种方法来比较map函数内部HTML元素的id与map函数外部对象的id。我正在寻找关于如何做到这一点以及最佳实践的一些指导。当点击帖子1它应该只显示帖子1.我已经把一个简单的例子放在一起,所以很容易看到我正在尝试做什么。
在filter方法中,如何比较click对象的id和从posts对象数组匹配的id。
import React, { Component } from 'react';
import { render } from 'react-dom';
class App extends Component {
constructor() {
super();
this.showPost = this.showPost.bind(this),
this.state = {
posts: [{
question: 'post 1',
body: 'BLAH BLAH BLAH BLAH',
postType: 'Question',
Id: 123,
},
{
question: 'post 2',
body: 'BLAH BLAH BLAH BLAH',
postType: 'Question',
Id: 133,
},
],
openedPost: false,
};
}
showPost() {
console.log("post shown");
this.setState({ openedPost: true });
}
render() {
const posts = this.state.posts.map((item) =>
<div key={item.Id}>
<h1 Id={item.Id} onClick={this.showPost}> {item.question} </h1>
</div>
)
if(this.state.openedPost) {
const clickedPost = this.state.posts.filter(function(item) {
return
})
}
return (
<div>
{posts}
{clickedPost}
</div>
);
}
}
render(<App />, document.getElementById('root'));
答案 0 :(得分:1)
我没有将id
作为DOM
属性传递并从DOM
读回来,而是建议使用组件(这是我认为的反应方式)。
让react
进行交易,然后触摸&#34; DOM
让The Diffing Algorithm and Reconciliation
你应该创建一个可以接受<Post />
作为道具的postId
组件,以及一个可以调用父处理程序并将其传递给它的onClick
处理程序相关的postId
。
一个正在运行的例子:
class Post extends React.Component {
handleClick = () => {
const { postId, onClick } = this.props;
onClick(postId);
}
render() {
const { question } = this.props;
return (
<div onClick={this.handleClick}>
<h1>
{question}
</h1>
</div>
);
}
}
class App extends React.Component {
constructor() {
super();
this.showPost = this.showPost.bind(this),
this.state = {
posts: [{
question: 'post 1',
body: '1: BLAH BLAH BLAH BLAH',
postType: 'Question',
Id: 123,
},
{
question: 'post 2',
body: '2: BLAH BLAH BLAH BLAH',
postType: 'Question',
Id: 133,
}],
openedPost: null
};
}
showPost = (postId) => {
console.log("post shown id:" + postId);
this.setState({ openedPost: postId });
}
renderPosts = () => {
const { posts } = this.state;
return posts.map(post => <Post key={post.Id} onClick={this.showPost} question={post.question} postId={post.Id} />);
}
render() {
const { posts, openedPost } = this.state;
const rendredPosts = this.renderPosts();
const clickedPost = openedPost && posts.find(item => item.Id == this.state.openedPost).body;
return (
<div>
{rendredPosts}
{clickedPost}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
修改强>
作为评论的后续内容:
所以在
return posts.map(post => <Post key={post.Id} onClick={this.showPost} question={post.question} postId={post.Id} />);
我们没有必要将ID传递给
this.showPost
你能解释清楚吗? 怎么知道抓住那个特定元素的id?
此方法返回<Post/>
组件的数组,此组件可以获得postId
的支柱(您可以随意命名)。如你所知,它还获得onClick
回调的支柱
在这个组件内部,我们有一个内部handleClick
处理程序,它调用从父进程传递的回调并在传递它时传递父进程传递的相同props.postId
。
handleClick = () => {
// see here we use both the onClick and postId props passed by the parent
const { postId, onClick } = this.props;
onClick(postId);
}
看到这是我努力理解的地方。为什么我们不会通过 item.Id到那个,它如何自动知道抓住id 点击了一下?
所以我希望您现在明白我们确实已经通过post.Id
而不是直接传递给onClick
回调,而是将其作为道具itemId
传递给组件,并且该组件通过onClick
使用此道具调用了this.props.itemId
。
在react
中,数据(应)以单向方式流动。
家长通过props
(或context
)将数据传递给儿童。
有时候,我们需要将数据从子节点传回父节点。在您的情况下,孩子应该在点击时传递其ID 这样做的方法是使用回调。父对孩子传递回调,孩子有责任调用此方法并向其注入一些数据。
当您将回调传递给DOM
元素时,您无法传回任何数据,因为DOM
元素不是您控制的组件。返回的唯一数据是触发器的event
(在这种情况下为click事件),您可以访问此事件的目标,即触发click事件的真实DOM
元素,从中抓取属性,例如id
如上所述The Diffing Algorithm and Reconciliation,这是一种不好的做法。
通过撰写组件来控制您的元素。
使用组件,您可以做一些逻辑或决定何时以及如何调用处理程序,它们将传递什么类型的数据,当然您可以重用它们并测试它们!
我希望能回答你的问题并帮助你更多地了解它。
答案 1 :(得分:0)
我会在post
方法中存储点击了showPost
。
showPost(event){
const clickedPost = this.state.posts.find( // .find is not supported in IE
post=>post.id===event.target.id
)
this.setState({clickedPost})
}