繁体   English   中英

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

[英]Rendering Content Conditionally in React JS Based on the state

我有一个页面呈现已发布的问题。 我想创建一个按钮,仅显示基于 state = {isAnswered: true} 的已回答问题。

如果 state isAnswered 为真,那么 onClick 将仅在 object 中 isAnswered 设置为真时显示已回答的问题。

我如何使用此过滤器按钮根据它们的 state 有条件地渲染它们。

function 是否应该存储为在渲染 function 或之前调用的常量?

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是一个数组。 数组中的每个元素都是一个 object ,具有多个属性,包括isAnswered

当你这样做时:

let {isAnswered} = this.state;

您正在寻找不存在的属性this.state.isAnswered 没有顶级isAnswered属性。 它存在于每个post object 中,并且每个帖子都不同。 因此,您需要查看循环内部isAnswered

老实说,这里有很多奇怪和倒退的地方。 不要在render()内部创建回调! 不要从回调中返回 JSX!

这是我清理它的尝试。 我正在向this.state添加一个属性,它告诉我们是否过滤帖子。 单击button更改this.state.isFiltered 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