我是一名反应灵敏的初学者,我有些概念很难掌握。如何识别反应中的状态,以及如何选择状态应放在哪个组件中? 我看到了“思考的例子”,但我听不懂。
答案 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端点获取一些帖子,并希望在我们的组件中逐一列出每个帖子。在这里,我们有两个组成部分:Posts
和Post
。一个聪明,另一个愚蠢。聪明的人负责获取工作,并将帖子传递给愚蠢的人。哑巴一无所知。它只知道它的支柱是支柱。聪明的人不会做任何与之相关的演示,而只是做其工作并传递数据。哑巴正在做演讲工作。另外,由于它不是有状态的,因此我们将其编写为功能组件,而不是类。
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组件时,您将了解状态应该存在的地方。但是,不要为此付出太多努力。开始编写组件,以后您可以自由地对其进行重构。