如何 show/hide array.map() 的项目
How to show/hide an item of array.map()
我想 show/hide JSX 的一部分取决于 isCommentShown
状态 属性。但是因为这部分在一个映射循环中 isCommentShown
作用于所有映射的项目,而不仅仅是当前的。所以当我 toggleComment
时,循环内的每个评论都是 shown/hidden。我想这可以通过将所有内容移动到一个单独的组件中来解决,因为每个组件都有自己的状态。但是我想知道如果没有那个我能不能解决这个问题。
const SearchResults = () => {
const [isCommentShown, setIsCommentShown] = useState(false);
const toggleComment = () => {
setIsCommentShown(!isCommentShown);
};
return (
<>
{props.search_results.map(obj =>
<div key={obj.id}>
{ obj.comment ? <img onClick={toggleComment}/> : null }
<div>{obj.text}</div>
{ isCommentShown ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
};
如果您一次只想显示一条评论,则必须存储要显示的评论 ID,而不是存储 true 或 false。唯一标识要展开的项目很重要
const SearchResults = () => {
const [commentShown, setCommentShown] = useState({});
const toggleComment = (id) => {
setCommentShown(prev => Boolean(!prev[id]) ? {...prev, [id]: true} : {...prev, [id]: false});
};
return (
<>
{props.search_results.map(obj =>
<div key={obj.id}>
{ obj.comment ? <img onClick={() => toggleComment(obj.id)}/> : null }
<div>{obj.text}</div>
{ commentShown[id] ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
};
如果您需要同时打开多个评论,您可以维护一个打开的 ID 映射
const SearchResults = () => {
const [commentShown, setCommentShown] = useState('');
const toggleComment = (id) => {
setCommentShown(prev => prev.commentShown !== id? id: '');
};
return (
<>
{props.search_results.map(obj =>
<div key={obj.id}>
{ obj.comment ? <img onClick={() => toggleComment(obj.id)}/> : null }
<div>{obj.text}</div>
{ commentShown === obj.id ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
};
使用 id 将切换定位到您想要的评论上。
更准确地说,使用状态来存储 show/hide 值,并将 id 传递给 onclick 事件以精确切换哪个评论。这应该可以完成工作:
class SearchResults extends React.Component {
constructor(props) {
super(props);
this.state = {};
for (let result of props.search_results) {
this.state[`${result.id}IsShown`] = true;
}
}
toggleComment(id) {
let key = `${result.id}IsShown`;
this.setState({[key]: !this.state[key]});
}
render() {
return (
<>
{this.props.search_results.map(result =>
<div key={result.id}>
{
result.comment
? <img onClick={() => toggleComment(result.id)}/>
: null
}
<div>{result.text}</div>
{ isCommentShown ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
}
}
您可以使用 useState
挂钩创建一个对象,它将所有搜索结果 ID 作为键和一个布尔值,指示是否应显示评论。
例子
const { useState, Fragment } = React;
const SearchResults = props => {
const [shownComments, setShownComments] = useState({});
const toggleComment = id => {
setShownComments(prevShownComments => ({
...prevShownComments,
[id]: !prevShownComments[id]
}));
};
return (
<Fragment>
{props.search_results.map(obj => (
<div key={obj.id}>
{obj.comment ? (
<button onClick={() => toggleComment(obj.id)}>Toggle</button>
) : null}
<div>{obj.text}</div>
{shownComments[obj.id] ? <p>{obj.comment}</p> : null}
</div>
))}
</Fragment>
);
};
ReactDOM.render(
<SearchResults
search_results={[
{ id: 0, text: "Foo bar", comment: "This is rad" },
{ id: 1, text: "Baz qux", comment: "This is nice" }
]}
/>,
document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
我想 show/hide JSX 的一部分取决于 isCommentShown
状态 属性。但是因为这部分在一个映射循环中 isCommentShown
作用于所有映射的项目,而不仅仅是当前的。所以当我 toggleComment
时,循环内的每个评论都是 shown/hidden。我想这可以通过将所有内容移动到一个单独的组件中来解决,因为每个组件都有自己的状态。但是我想知道如果没有那个我能不能解决这个问题。
const SearchResults = () => {
const [isCommentShown, setIsCommentShown] = useState(false);
const toggleComment = () => {
setIsCommentShown(!isCommentShown);
};
return (
<>
{props.search_results.map(obj =>
<div key={obj.id}>
{ obj.comment ? <img onClick={toggleComment}/> : null }
<div>{obj.text}</div>
{ isCommentShown ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
};
如果您一次只想显示一条评论,则必须存储要显示的评论 ID,而不是存储 true 或 false。唯一标识要展开的项目很重要
const SearchResults = () => {
const [commentShown, setCommentShown] = useState({});
const toggleComment = (id) => {
setCommentShown(prev => Boolean(!prev[id]) ? {...prev, [id]: true} : {...prev, [id]: false});
};
return (
<>
{props.search_results.map(obj =>
<div key={obj.id}>
{ obj.comment ? <img onClick={() => toggleComment(obj.id)}/> : null }
<div>{obj.text}</div>
{ commentShown[id] ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
};
如果您需要同时打开多个评论,您可以维护一个打开的 ID 映射
const SearchResults = () => {
const [commentShown, setCommentShown] = useState('');
const toggleComment = (id) => {
setCommentShown(prev => prev.commentShown !== id? id: '');
};
return (
<>
{props.search_results.map(obj =>
<div key={obj.id}>
{ obj.comment ? <img onClick={() => toggleComment(obj.id)}/> : null }
<div>{obj.text}</div>
{ commentShown === obj.id ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
};
使用 id 将切换定位到您想要的评论上。
更准确地说,使用状态来存储 show/hide 值,并将 id 传递给 onclick 事件以精确切换哪个评论。这应该可以完成工作:
class SearchResults extends React.Component {
constructor(props) {
super(props);
this.state = {};
for (let result of props.search_results) {
this.state[`${result.id}IsShown`] = true;
}
}
toggleComment(id) {
let key = `${result.id}IsShown`;
this.setState({[key]: !this.state[key]});
}
render() {
return (
<>
{this.props.search_results.map(result =>
<div key={result.id}>
{
result.comment
? <img onClick={() => toggleComment(result.id)}/>
: null
}
<div>{result.text}</div>
{ isCommentShown ? <p>{obj.comment}</p> : null }
</div>
)}
</>
);
}
}
您可以使用 useState
挂钩创建一个对象,它将所有搜索结果 ID 作为键和一个布尔值,指示是否应显示评论。
例子
const { useState, Fragment } = React;
const SearchResults = props => {
const [shownComments, setShownComments] = useState({});
const toggleComment = id => {
setShownComments(prevShownComments => ({
...prevShownComments,
[id]: !prevShownComments[id]
}));
};
return (
<Fragment>
{props.search_results.map(obj => (
<div key={obj.id}>
{obj.comment ? (
<button onClick={() => toggleComment(obj.id)}>Toggle</button>
) : null}
<div>{obj.text}</div>
{shownComments[obj.id] ? <p>{obj.comment}</p> : null}
</div>
))}
</Fragment>
);
};
ReactDOM.render(
<SearchResults
search_results={[
{ id: 0, text: "Foo bar", comment: "This is rad" },
{ id: 1, text: "Baz qux", comment: "This is nice" }
]}
/>,
document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>