将元素添加到状态 React
Posted
技术标签:
【中文标题】将元素添加到状态 React【英文标题】:Add element to a state React 【发布时间】:2018-06-01 04:30:03 【问题描述】:我已经有了这样的状态:
this.setState(
conversation:
(
<div>
conversation.map(element =>
if (element.id === this.props.id)
return(
<div className="row msg_container base_sent">
<div className="col-md-10 col-xs-10">
<div className="messages msg_sent">
<p>element.message</p>
</div>
</div>
</div>
)
else
return(
<div className="row msg_container base_receive">
<div className="col-md-10 col-xs-10">
<div className="messages msg_receive">
<p>element.message</p>
</div>
</div>
</div>
)
)
</div>
)
)
现在我想用新信息更新它。所以添加另一个 div 到它。
类似的东西:
this.setState(conversation: previousConversation + new div)
我该怎么做?或者我需要从零开始设置一个新状态
【问题讨论】:
在状态中存储 jsx 似乎不是一个好主意。实际上,我以前从未见过有人这样做... 这应该不是问题。我认为你想要的是一个映射(考虑导入 lodash 库并使用 _.map([1,2,3], function(x) ...);)所以当它的状态改变时,react 会处理添加消息自己 【参考方案1】:根据 React 文档 (webarchive source):
状态应该怎样?
状态应该包含组件的事件处理程序可能会更改以触发 UI 更新的数据。 在实际应用中,这些数据往往非常小并且可以通过 JSON 序列化。在构建有状态组件时,请考虑其状态的最小可能表示形式,并且仅将这些属性存储在
this.state
中。在render()
内部,只需根据此状态计算您需要的任何其他信息。你会发现以这种方式思考和编写应用程序往往会导致最正确的应用程序,因为向状态添加冗余或计算值意味着你需要显式地保持它们同步,而不是依赖 React 为你计算它们。什么不应该进入状态?
计算数据:不用担心根据状态预先计算值 - 如果你做所有事情,更容易确保你的 UI 是一致的
this.state
应该只包含最小的 表示 UI 状态所需的数据量。因此,它应该 不包含:render()
内的计算。例如,如果您有一个列表数组 状态中的项目,并且您想将计数呈现为字符串,只需 在您的render()
中渲染this.state.listItems.length + ' list items'
方法而不是将其存储在状态中。 React 组件: 根据底层的 props 和状态在render()
中构建它们。 来自道具的重复数据:尽可能使用道具作为事实来源。一 在 state 中存储 props 的有效用途是能够知道它以前的 值,因为道具会随着时间而改变。
在你的情况下,将你的 html 移动到你的渲染函数中。然后在您的状态中存储一个条件或数据,该条件或数据将用于触发向您的 html 添加另一个 div,方法是有条件地呈现一些 html,或者基于向您的状态添加更多数据,将另一个 div 添加到 .map 函数内的数组中.
例子:
Class Example render React.Component
state =
comments: [
message:"comment 1", id: 1, timeStamp: "" ,
message:"comment 2", id: 2, timeStamp: "" ,
message:"comment 3", id: 3, timeStamp: ""
]
componentDidMount = () =>
//update data from api...
.then(data => this.setState( comments: data ))
render()
conversation.map(element =>
if (element.id === this.props.id)
return(
<div className="row msg_container base_sent">
<div className="col-md-10 col-xs-10">
<div className="messages msg_sent">
<p>element.message</p>
</div>
</div>
</div>
)
else
return(
<div className="row msg_container base_receive">
<div className="col-md-10 col-xs-10">
<div className="messages msg_receive">
<p>element.message</p>
</div>
</div>
</div>
)
)
【讨论】:
你能举个例子吗? 添加了一个例子。我不知道您的应用程序的上下文,所以我只是假设您从 api 调用中获取新数据 我有类似的东西,但我需要实时反馈。我通过套接字实时收到新消息,这就是我提出问题的真正原因 我建议使用 socket.io-client 库之类的东西来处理套接字之间的实时反馈。尝试浏览这篇文章以了解如何执行此操作。 medium.com/dailyjs/… 这是库的 npm npmjs.com/package/socket.io-client 完全不喜欢这样的答案,说你应该做什么,而没有说你为什么应该这样做。如果你不解释你的理由,我无法知道你的答案是否好。【参考方案2】:我认为将 jsx 组件存储在组件的状态中不是一个好主意。我认为您应该只将数据保存在渲染组件所需的状态中。
如果你真的想将 jsx 存储在 state 中,为什么不将你的 'conversation' 属性定义为数组呢?然后您就可以向其中添加新组件了。
this.setState(
conversation: [
(<div>first</div)
]
);
const currentConversation = state.conversation;
currentConversation.push((<div>new div</div>));
this.setState(conversation: currentConversation)
但最好只存储数据,即'first'和'new div'
【讨论】:
当我向我的服务器发送消息时,我认为打电话并接受新对话是没有用的。所以我决定向现有状态添加一条新消息。当我刷新页面时,拨打电话以获取新对话。我认为这很有效,可以帮助用户看到实时聊天。我不知道是最好的解决方案 这实际上很好用!但我不知道是否是最好的方法。考虑到我正在使用套接字实时接收新消息 如果它适用于您的应用程序,那很好:)。但正如之前和 MEnf 所指出的,我认为最好只将数据存储在状态中,无论您是否使用套接字。它将使您的维护更容易。如果您希望您的用户看到实时聊天,您还可以考虑为您的服务调用实施乐观响应 只要是在状态中使用的简单的 HTML 元素,它似乎工作得很好。一旦使用了自定义的 React 元素,它的生命周期就会一团糟。因此,根据经验,永远不要将 JSX 置于状态,甚至在渲染周期之外。以上是关于将元素添加到状态 React的主要内容,如果未能解决你的问题,请参考以下文章
React - Apollo 客户端,如何将查询结果添加到状态
react篇章-React State(状态)-将生命周期方法添加到类中