基于状态在 React JS 中有条件地渲染内容
Rendering Content Conditionally in React JS Based on the state
我有一个页面可以呈现已发布的问题。我想创建一个按钮,仅根据状态 = {isAnswered: true} 显示已回答的问题。
如果状态 isAnswered 为真,则 onClick 将仅在对象中将 isAnswered 设置为真时显示已回答的问题。
我如何使用这个过滤器按钮根据它们的状态有条件地呈现它们。
函数应该存储为渲染函数中调用的常量还是在此之前?
this.state.posts是后端这些对象的数组:
这是我尝试过的。
class Posts extends Component {
state = {
posts: []
}
render () {
let posts = <p style={{ textAlign: 'center' }}>Something went wrong!</p>;
let {isAnswered} = this.state;
const renderAuthButton = () => {
if (isAnswered === true) {
if ( !this.state.error ) {
posts = this.state.posts.map( (post) => {
return (
<Post
key={post.key}
id={post.key}
title={post.title}
type={post.type}
body={post.body}
answer={post.answer}
onChange={(value, id) => this.postAnswerHandler(value,id)}
clicked={(body) => this.displayAnswerHandler(body)}
/>
);
} );
}
}
}
}
return (
<button onClick={renderAuthButton()}>Filter</button>
{posts}
)
您误解了您的数据结构。 this.state
有一个 属性 this.state.posts
这是一个数组。数组中的每个元素都是一个具有多个属性的对象,包括 isAnswered
.
当你这样做时:
let {isAnswered} = this.state;
您要找的 属性 this.state.isAnswered
不存在。没有顶级isAnswered
属性。它存在于每个 post
对象中并且对于每个 post 都是不同的。因此,您需要查看循环中的 isAnswered
。
老实说,这里有很多奇怪和倒退的地方。不要在 render()
中创建回调!不要 return 回调中的 JSX!
这是我清理它的尝试。我在 this.state
中添加了一个 属性,它告诉我们是否过滤 post。单击 button
更改 this.state.isFiltered
。 render
函数根据当前状态适当呈现。
class Posts extends Component {
state = {
posts: [],
isFiltered: false,
isError: false
};
async componentDidMount() {
// do your API fetch and set the state for `posts` and `isError`
try {
const fetchedPosts = someApiFunction();
this.setState({
posts: fetchedPosts
});
} catch (error) {
this.setState({
isError: true
});
}
}
onClickFilter = () => {
// toggles filter on and off
this.setState((prevState) => ({
isFiltered: !prevState.isFiltered
}));
};
render() {
if (this.state.isError) {
return <p style={{ textAlign: "center" }}>Something went wrong!</p>;
}
// show only answered posts if isFiltered is true, or all posts if false
const visiblePosts = this.state.isFiltered
? this.state.posts.filter((post) => post.isAnswered)
: this.state.posts;
return (
<>
<button onClick={this.onClickFilter}>Filter</button>
{visiblePosts.map((post) => {
return (
<Post
key={post.key}
id={post.key}
title={post.title}
type={post.type}
body={post.body}
answer={post.answer}
onChange={(value, id) => this.postAnswerHandler(value, id)}
clicked={(body) => this.displayAnswerHandler(body)}
/>
);
})}
</>
);
}
}
我有一个页面可以呈现已发布的问题。我想创建一个按钮,仅根据状态 = {isAnswered: true} 显示已回答的问题。
如果状态 isAnswered 为真,则 onClick 将仅在对象中将 isAnswered 设置为真时显示已回答的问题。
我如何使用这个过滤器按钮根据它们的状态有条件地呈现它们。
函数应该存储为渲染函数中调用的常量还是在此之前?
this.state.posts是后端这些对象的数组:
这是我尝试过的。
class Posts extends Component {
state = {
posts: []
}
render () {
let posts = <p style={{ textAlign: 'center' }}>Something went wrong!</p>;
let {isAnswered} = this.state;
const renderAuthButton = () => {
if (isAnswered === true) {
if ( !this.state.error ) {
posts = this.state.posts.map( (post) => {
return (
<Post
key={post.key}
id={post.key}
title={post.title}
type={post.type}
body={post.body}
answer={post.answer}
onChange={(value, id) => this.postAnswerHandler(value,id)}
clicked={(body) => this.displayAnswerHandler(body)}
/>
);
} );
}
}
}
}
return (
<button onClick={renderAuthButton()}>Filter</button>
{posts}
)
您误解了您的数据结构。 this.state
有一个 属性 this.state.posts
这是一个数组。数组中的每个元素都是一个具有多个属性的对象,包括 isAnswered
.
当你这样做时:
let {isAnswered} = this.state;
您要找的 属性 this.state.isAnswered
不存在。没有顶级isAnswered
属性。它存在于每个 post
对象中并且对于每个 post 都是不同的。因此,您需要查看循环中的 isAnswered
。
老实说,这里有很多奇怪和倒退的地方。不要在 render()
中创建回调!不要 return 回调中的 JSX!
这是我清理它的尝试。我在 this.state
中添加了一个 属性,它告诉我们是否过滤 post。单击 button
更改 this.state.isFiltered
。 render
函数根据当前状态适当呈现。
class Posts extends Component {
state = {
posts: [],
isFiltered: false,
isError: false
};
async componentDidMount() {
// do your API fetch and set the state for `posts` and `isError`
try {
const fetchedPosts = someApiFunction();
this.setState({
posts: fetchedPosts
});
} catch (error) {
this.setState({
isError: true
});
}
}
onClickFilter = () => {
// toggles filter on and off
this.setState((prevState) => ({
isFiltered: !prevState.isFiltered
}));
};
render() {
if (this.state.isError) {
return <p style={{ textAlign: "center" }}>Something went wrong!</p>;
}
// show only answered posts if isFiltered is true, or all posts if false
const visiblePosts = this.state.isFiltered
? this.state.posts.filter((post) => post.isAnswered)
: this.state.posts;
return (
<>
<button onClick={this.onClickFilter}>Filter</button>
{visiblePosts.map((post) => {
return (
<Post
key={post.key}
id={post.key}
title={post.title}
type={post.type}
body={post.body}
answer={post.answer}
onChange={(value, id) => this.postAnswerHandler(value, id)}
clicked={(body) => this.displayAnswerHandler(body)}
/>
);
})}
</>
);
}
}