[英]Rendering Content Conditionally in React JS Based on the state
I have a page that renders questions that have been posted.我有一个页面呈现已发布的问题。 I want to create a button that displays only answered questions based on the state = {isAnswered: true}.
我想创建一个按钮,仅显示基于 state = {isAnswered: true} 的已回答问题。
Is the state isAnswered is true then onClick will display answered questions only where isAnswered is set to true in the object.如果 state isAnswered 为真,那么 onClick 将仅在 object 中 isAnswered 设置为真时显示已回答的问题。
How can I used this Filter button to conditionally render these based on their state.我如何使用此过滤器按钮根据它们的 state 有条件地渲染它们。
Should the function be stored as constant called in the render function or before this? function 是否应该存储为在渲染 function 或之前调用的常量?
this.state.posts is an array of these objects on the back end: this.state.posts 是后端这些对象的数组:
Here is what I have attempted.这是我尝试过的。
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}
)
You are misinterpreting your data structure.您误解了您的数据结构。
this.state
has a property this.state.posts
which is an array. this.state
有一个属性this.state.posts
是一个数组。 Each element in the array is an object with multiple properties including isAnswered
.数组中的每个元素都是一个 object ,具有多个属性,包括
isAnswered
。
When you do this:当你这样做时:
let {isAnswered} = this.state;
You are looking for a property this.state.isAnswered
which does not exist.您正在寻找不存在的属性
this.state.isAnswered
。 There is no top-level isAnswered
property.没有顶级
isAnswered
属性。 It is something that exists within each post
object and is different for every post.它存在于每个
post
object 中,并且每个帖子都不同。 So you need to be looking at isAnswered
inside of your loop.因此,您需要查看循环内部的
isAnswered
。
There's honestly a lot that's weird and backwards here.老实说,这里有很多奇怪和倒退的地方。 Don't create a callback inside of
render()
!不要在
render()
内部创建回调! Don't return JSX from a callback!不要从回调中返回 JSX!
Here's my attempt to clean it up.这是我清理它的尝试。 I am adding a property to
this.state
which tells us whether or not to filter the posts.我正在向
this.state
添加一个属性,它告诉我们是否过滤帖子。 Clicking the button
changes this.state.isFiltered
.单击
button
更改this.state.isFiltered
。 The render
function renders appropriately based on the current state. render
function 根据当前 state 进行适当渲染。
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)}
/>
);
})}
</>
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.