赞
踩
本文翻译自:What is the difference between state and props in React?
I was watching a Pluralsight course on React and the instructor stated that props should not be changed. 我正在观看有关React的Pluralsight课程,并且讲师说不应更改道具。 I'm now reading an article (uberVU/react-guide) on props vs. state and it says 我现在正在阅读有关道具与状态的文章(uberVU / react-guide) ,它说
Both props and state changes trigger a render update. 道具和状态更改都会触发渲染更新。
Later in the article it says: 文章稍后会说:
Props (short for properties) are a Component's configuration, its options if you may. 道具(属性的缩写)是组件的配置,如果可以的话,它是选项。 They are received from above and immutable. 它们是从上方接收的,并且是不变的。
getInitialState
? 如果您有React组件需要的数据,是否应该通过prop或通过getInitialState
在React组件中进行设置来传递数据? 参考:https://stackoom.com/question/1tRpe/React中的state和props有什么区别
Props and state are related. 道具和状态有关。 The state of one component will often become the props of a child component. 一个组件的状态通常会成为子组件的道具。 Props are passed to the child within the render method of the parent as the second argument to React.createElement()
or, if you're using JSX, the more familiar tag attributes. 道具作为React.createElement()
的第二个参数传递给父对象的render方法中的子对象,或者,如果您使用的是JSX,则将其作为更熟悉的标签属性。
<MyChild name={this.state.childsName} />
The parent's state value of childsName
becomes the child's this.props.name
. 父级的childsName
状态值成为子级的this.props.name
。 From the child's perspective, the name prop is immutable. 从孩子的角度来看,prop这个名字是一成不变的。 If it needs to be changed, the parent should just change its internal state: 如果需要更改,则父级只需更改其内部状态即可:
this.setState({ childsName: 'New name' });
and React will propagate it to the child for you. React将为您将其传播给孩子。 A natural follow-on question is: what if the child needs to change its name prop? 接natural而来的自然问题是:如果孩子需要更改道具名称该怎么办? This is usually done through child events and parent callbacks. 这通常是通过子事件和父回调完成的。 The child might expose an event called, for example, onNameChanged
. 子级可能会公开一个事件,例如onNameChanged
。 The parent would then subscribe to the event by passing a callback handler. 然后,父级将通过传递回调处理程序来订阅事件。
<MyChild name={this.state.childsName} onNameChanged={this.handleName} />
The child would pass its requested new name as an argument to the event callback by calling, eg, this.props.onNameChanged('New name')
, and the parent would use the name in the event handler to update its state. 子级将通过调用例如this.props.onNameChanged('New name')
来将其请求的新名称作为参数传递给事件回调,而父级将在事件处理程序中使用该名称来更新其状态。
- handleName: function(newName) {
- this.setState({ childsName: newName });
- }
For parent-child communication, simply pass props. 对于亲子交流,只需传递道具即可。
Use state to store the data your current page needs in your controller-view. 使用状态将当前页面所需的数据存储在控制器视图中。
Use props to pass data & event handlers down to your child components. 使用道具将数据和事件处理程序传递到您的子组件。
These lists should help guide you when working with data in your components. 这些列表应有助于指导您在组件中使用数据。
Props 道具
State 州
For communication between two components that don't have a parent-child relationship, you can set up your own global event system. 要在没有父子关系的两个组件之间进行通信,可以设置自己的全局事件系统。 Subscribe to events in componentDidMount(), unsubscribe in componentWillUnmount(), and call setState() when you receive an event. 订阅componentDidMount()中的事件,取消订阅componentWillUnmount()中的事件,并在收到事件时调用setState()。 Flux pattern is one of the possible ways to arrange this. 助焊剂模式是解决此问题的一种可能方法。 - https://facebook.github.io/react/tips/communicate-between-components.html -https://facebook.github.io/react/tips/communicate-between-components.html
What Components Should Have State? 哪些组件应具有状态?
Most of your components should simply take some data from props and render it. 您的大多数组件都应该简单地从props中获取一些数据并进行渲染。 However, sometimes you need to respond to user input, a server request or the passage of time. 但是,有时您需要响应用户输入,服务器请求或时间的流逝。 For this you use state. 为此,请使用状态。
Try to keep as many of your components as possible stateless . 尝试使尽可能多的组件保持无状态 。 By doing this you'll isolate the state to its most logical place and minimize redundancy, making it easier to reason about your application. 通过这样做,您可以将状态隔离到最逻辑的位置,并最大程度地减少冗余,从而使推理应用程序更加容易。
A common pattern is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via props. 一种常见的模式是创建几个仅呈现数据的无状态组件,并在层次结构中的上方放置一个有状态组件,该状态组件通过道具将其状态传递给子组件。 The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way. 有状态组件封装了所有交互逻辑,而无状态组件负责以声明的方式呈现数据。 - https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-components-should-have-state -https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-components-should-have-state
What Should Go in State? 什么状态?
State should contain data that a component's event handlers may change to trigger a UI update. 状态应包含组件的事件处理程序可能更改以触发UI更新的数据。 In real apps this data tends to be very small and JSON-serializable. 在实际的应用程序中,此数据往往很小并且可以JSON序列化。 When building a stateful component, think about the minimal possible representation of its state, and only store those properties in this.state. 在构建有状态组件时,请考虑其状态的最小可能表示,并仅将这些属性存储在this.state中。 Inside of render() simply compute any other information you need based on this state. 在render()内部,仅根据此状态计算您需要的任何其他信息。 You'll find that thinking about and writing applications in this way tends to lead to the most correct application, since adding redundant or computed values to state means that you need to explicitly keep them in sync rather than rely on React computing them for you. 您会发现以这种方式考虑和编写应用程序往往会导致最正确的应用程序,因为在状态中添加冗余或计算值意味着您需要显式保持它们同步,而不是依靠React为您计算它们。 - https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-should-go-in-state -https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-should-go-in-state
Basically, props and state are two ways the component can know what and how to render. 基本上,道具和状态是组件可以知道什么以及如何渲染的两种方式。 Which part of the application state belongs to state and which to some top-level store, is more related to your app design, than to how React works. 应用程序状态的哪一部分属于状态,哪一部分属于某个顶级存储,与您的应用程序设计有关,而不是与React的工作方式有关。 The simplest way to decide, IMO, is to think, whether this particular piece of data is useful for application as a whole, or it's some local information. IMO决定最简单的方法是思考,这块特定的数据对于整个应用程序是否有用,还是某些本地信息。 Also, it's important to not duplicate state, so if some piece of data can be calculated from props - it should calculated from props. 另外,不要复制状态也很重要,因此,如果可以通过props计算某些数据-应该从props计算出来。
For example, let's say you have some dropdown control (which wraps standart HTML select for custom styling), which can a) select some value from list, and b) be opened or closed (ie, the options list displayed or hidden). 例如,假设您有一些下拉控件(包装用于自定义样式的标准HTML选择),它可以a)从列表中选择一些值,以及b)打开或关闭(即显示或隐藏选项列表)。 Now, let's say your app displays a list of items of some sort and your dropdown controls filter for list entries. 现在,假设您的应用显示了某种类型的项目列表,并且您的下拉控件过滤了列表项。 Then, it would be best to pass active filter value as a prop, and keep opened/closed state local. 然后,最好将活动过滤器值作为参数传递,并保持本地打开/关闭状态。 Also, to make it functional, you would pass an onChange handler from parent component, which would be called inside dropdown element and send updated information (new selected filter) to the store immediately. 另外,为使其正常运行,您将从父组件传递一个onChange处理程序,该处理程序将在dropdown元素内调用,并立即将更新的信息(新选择的过滤器)发送到商店。 On the other hand, opened/closed state can be kept inside dropdown component, because the rest of the application doesn't really care if the control is opened, until user actually changes it value. 另一方面,打开/关闭状态可以保留在下拉组件中,因为应用程序的其余部分并不真正关心控件是否打开,直到用户实际更改其值为止。
The following code is not completely working, it needs css and handling dropdown click/blur/change events, but I wanted to keep example minimal. 以下代码无法完全正常运行,它需要CSS并处理下拉click / blur / change事件,但我想尽量减少示例。 Hope it helps to understand the difference. 希望它有助于理解差异。
- const _store = {
- items: [
- { id: 1, label: 'One' },
- { id: 2, label: 'Two' },
- { id: 3, label: 'Three', new: true },
- { id: 4, label: 'Four', new: true },
- { id: 5, label: 'Five', important: true },
- { id: 6, label: 'Six' },
- { id: 7, label: 'Seven', important: true },
- ],
- activeFilter: 'important',
- possibleFilters: [
- { key: 'all', label: 'All' },
- { key: 'new', label: 'New' },
- { key: 'important', label: 'Important' }
- ]
- }
-
- function getFilteredItems(items, filter) {
- switch (filter) {
- case 'all':
- return items;
-
- case 'new':
- return items.filter(function(item) { return Boolean(item.new); });
-
- case 'important':
- return items.filter(function(item) { return Boolean(item.important); });
-
- default:
- return items;
- }
- }
-
- const App = React.createClass({
- render: function() {
- return (
- <div>
- My list:
-
- <ItemList items={this.props.listItems} />
- <div>
- <Dropdown
- onFilterChange={function(e) {
- _store.activeFilter = e.currentTarget.value;
- console.log(_store); // in real life, some action would be dispatched here
- }}
- filterOptions={this.props.filterOptions}
- value={this.props.activeFilter}
- />
- </div>
- </div>
- );
- }
- });
-
- const ItemList = React.createClass({
- render: function() {
- return (
- <div>
- {this.props.items.map(function(item) {
- return <div key={item.id}>{item.id}: {item.label}</div>;
- })}
- </div>
- );
- }
- });
-
- const Dropdown = React.createClass({
- getInitialState: function() {
- return {
- isOpen: false
- };
- },
-
- render: function() {
- return (
- <div>
- <select
- className="hidden-select"
- onChange={this.props.onFilterChange}
- value={this.props.value}>
- {this.props.filterOptions.map(function(option) {
- return <option value={option.key} key={option.key}>{option.label}</option>
- })}
- </select>
-
- <div className={'custom-select' + (this.state.isOpen ? ' open' : '')} onClick={this.onClick}>
- <div className="selected-value">{this.props.activeFilter}</div>
- {this.props.filterOptions.map(function(option) {
- return <div data-value={option.key} key={option.key}>{option.label}</div>
- })}
- </div>
- </div>
- );
- },
-
- onClick: function(e) {
- this.setState({
- isOpen: !this.state.isOpen
- });
- }
- });
-
- ReactDOM.render(
- <App
- listItems={getFilteredItems(_store.items, _store.activeFilter)}
- filterOptions={_store.possibleFilters}
- activeFilter={_store.activeFilter}
- />,
- document.getElementById('root')
- );
The props vs state summary I like best is here: react-guide Big hat tip to those guys. 我最喜欢的道具与状态摘要在这里: react-guide那些家伙的大礼帽。 Below is an edited version of that page: 以下是该页面的编辑版本:
tl;dr If a Component needs to alter one of its attributes at some point in time, that attribute should be part of its state, otherwise it should just be a prop for that Component. tl; dr如果某个组件需要在某个时间点更改其属性之一,则该属性应该是其状态的一部分,否则应仅作为该组件的支持。
Props (short for properties) are a Component's configuration. 道具(属性的缩写)是组件的配置。 They are received from above and immutable as far as the Component receiving them is concerned. 它们是从上方接收的,并且就接收它们的组件而言是不变的。 A Component cannot change its props, but it is responsible for putting together the props of its child Components. 组件无法更改其道具,但它负责将其子组件的道具放在一起。 Props do not have to just be data -- callback functions may be passed in as props. 道具不必只是数据-回调函数可以作为道具传递。
The state is a data structure that starts with a default value when a Component mounts. 状态是一个数据结构,在安装组件时,该结构以默认值开头。 It may be mutated across time, mostly as a result of user events. 它可能会随时间变化,这主要是由于用户事件造成的。
A Component manages its own state internally. 组件在内部管理自己的状态。 Besides setting an initial state, it has no business fiddling with the state of its children. 除了设置初始状态外,它还没有摆弄孩子状态的事情。 You might conceptualize state as private to that component. 您可以将状态概念化为该组件的私有状态。
props state Can get initial value from parent Component? Yes Yes Can be changed by parent Component? Yes No Can set default values inside Component?* Yes Yes Can change inside Component? No Yes Can set initial value for child Components? Yes Yes Can change in child Components? Yes No
State is optional. 状态是可选的。 Since state increases complexity and reduces predictability, a Component without state is preferable. 由于状态会增加复杂性并降低可预测性,因此最好使用无状态的组件。 Even though you clearly can't do without state in an interactive app, you should avoid having too many Stateful Components. 即使您显然不能在交互式应用程序中没有状态,也应避免有太多的有状态组件。
Stateless Component Only props, no state. 无状态组件仅道具,无状态。 There's not much going on besides the render() function. 除了render()函数外,没有什么其他事情了。 Their logic revolves around the props they receive. 他们的逻辑围绕着他们收到的道具。 This makes them very easy to follow, and to test. 这使得它们非常易于遵循和测试。
Stateful Component Both props and state. 状态组件道具和状态。 These are used when your component must retain some state. 当您的组件必须保留某些状态时,将使用它们。 This is a good place for client-server communication (XHR, web sockets, etc.), processing data and responding to user events. 这是进行客户端与服务器通信(XHR,Web套接字等),处理数据和响应用户事件的好地方。 These sort of logistics should be encapsulated in a moderate number of Stateful Components, while all visualization and formatting logic should move downstream into many Stateless Components. 这类物流应封装在适量的状态组件中,而所有可视化和格式逻辑应向下游移动到许多无状态组件中。
在回答有关道具是不可变的最初问题时,就子组件而言 ,据说道具是不可变的,但在父组件中却是可变的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。