简体   繁体   English

基于 state 在 React JS 中有条件地渲染内容

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM