基于状态在 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.isFilteredrender 函数根据当前状态适当呈现。

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)}
            />
          );
        })}
      </>
    );
  }
}