选择状态应参与的组件

时间:2018-07-20 19:22:51

标签: reactjs

我是一名反应灵敏的初学者,我有些概念很难掌握。如何识别反应中的状态,以及如何选择状态应放在哪个组件中? 我看到了“思考的例子”,但我听不懂。

1 个答案:

答案 0 :(得分:0)

实际上,有很多不错的文章,博客条目甚至是答案。您可以找到这些并尝试编写一些代码。当您使用React编写代码时,您将了解您需要在哪里,不需要在哪里。这就是为什么您的问题被否决的原因。

我不太理解“如何在React中识别状态”的问题,但是如果您的组件依赖于要渲染并显示一些结果的数据,则可以将这些数据置于状态中。状态更改,组件重新渲染并根据状态显示结果。考虑一下最基本的Counter示例。

class Counter extends React.Component {
  state = {
    value: 0,
  }
  
  upIt = () => this.setState(prevState => ({
    value: prevState.value + 1,
  }))
  
  downIt = () => this.setState(prevState => ({
    value: prevState.value - 1,
  }))
  
  render() {
    return (
      <div>
      Value is now: {this.state.value}
      <hr />
      <button onClick={this.upIt}>Up</button>
      <button onClick={this.downIt}>Down</button>
      </div>
    );
  }
}

ReactDOM.render(
  <Counter />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

此组件应显示计数器值,因此每次单击都需要对其进行更新。我们要么以某种方式获得此值作为道具,要么将其保持在状态中。

现在,哪个组件应该保持状态,哪个不应该保持状态?首先阅读this superb article

这不是精确的科学,但是有最佳实践。您将拥有智能或有状态的组件,而您将拥有愚蠢或无状态的纯组件。智能组件将具有状态,并将状态传递给其他哑组件以执行其他操作。哑组件不会知道任何状态,因此它们不会在任何地方改变任何状态。他们将获得数据作为道具并完成工作。

现在让我们来看另一个稍微复杂的例子。我们从API端点获取一些帖子,并希望在我们的组件中逐一列出每个帖子。在这里,我们有两个组成部分:PostsPost。一个聪明,另一个愚蠢。聪明的人负责获取工作,并将帖子传递给愚蠢的人。哑巴一无所知。它只知道它的支柱是支柱。聪明的人不会做任何与之相关的演示,而只是做其工作并传递数据。哑巴正在做演讲工作。另外,由于它不是有状态的,因此我们将其编写为功能组件,而不是类。

class Posts extends React.Component {
  state = {
    posts: [],
  }
  
  componentDidMount() {
      fetch( "https://jsonplaceholder.typicode.com/posts" )
        .then( data => data.json() )
        .then( posts => this.setState({posts}) )
    }
  
  render() {
    return (
      <div>
      {
        this.state.posts.map( post =>
          <Post post={post} />
        )
      }
      </div>
    );
  }
}

const styles = {
  postContainer: {
    border: "1px solid black",
    backgroundColor: "gray",
    marginBottom: "5px",
  },
  postBody: {
    color: "white",
  },
  userInfo: {
    fontStyle: "italic",
  },
}

const Post = ({post}) => (
  <div style={styles.postContainer}>
    <p>Post ID: {post.id}</p>
    <h4>{post.title}</h4>
    <p style={styles.postBody}>{post.body}</p>
    <p style={styles.userInfo}>Sent by user with ID: {post.userId}</p>
  </div>
);


ReactDOM.render(
  <Posts />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

让我们走的更远。如果我们想阅读一篇帖子并使其消失,该怎么办?我们已经在Posts组件中添加了状态,让我们对其进行改进。添加第二个属性作为read并写下幻想!函数将帖子的ID添加到此read状态字段。然后使用过滤器魔术功能隐藏这些帖子。在这里,我们还将回调函数传递给我们的哑组件,并通过一个按钮将帖子的ID传递回智能组件,而该智能组件会改变状态而不是哑组件。

class Posts extends React.Component {
  state = {
    posts: [],
    read: [],
  }
  
  componentDidMount() {
      fetch( "https://jsonplaceholder.typicode.com/posts" )
        .then( data => data.json() )
        .then( posts => this.setState({posts}) )
  }
  
  setRead = ( id ) => this.setState( prevState => ({
    read: [ ...prevState.read, id ],
  }));
    
  
  render() {
    return (
      <div>
      {
        this.state.posts
        .filter( post => !this.state.read.includes(post.id) )
        .map( post =>
          <Post post={post} setRead={this.setRead} />
        )
      }
      </div>
    );
  }
}

const styles = {
  postContainer: {
    border: "1px solid black",
    backgroundColor: "gray",
    marginBottom: "5px",
  },
  postBody: {
    color: "white",
  },
  userInfo: {
    fontStyle: "italic",
  },
}

const Post = ({post, setRead}) => {
  const handleRead = () => setRead(post.id);

  return (
    <div style={styles.postContainer}>
      <p>Post ID: {post.id}</p>
      <h4>{post.title}</h4>
      <p style={styles.postBody}>{post.body}</p>
      <p style={styles.userInfo}>Sent by user with ID: {post.userId}</p>
      <button onClick={handleRead}>Set read</button>
    </div>
  );
}


ReactDOM.render(
  <Posts />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

因此,当您编写React组件时,您将了解状态应该存在的地方。但是,不要为此付出太多努力。开始编写组件,以后您可以自由地对其进行重构。