React.js的一大优势应该是服务器端渲染.问题是密钥功能React.renderComponentToString()是同步的,这使得在服务器上呈现组件层次结构时无法加载任何异步数据.
假设我有一个用于评论的通用组件,我可以在页面的任何位置删除它.它只有一个属性,某种标识符(例如文章的id在其下面放置注释),其他所有内容都由组件本身处理(加载,添加,管理注释).
我非常喜欢Flux架构,因为它使很多东西变得更容易,而且它的商店非常适合在服务器和客户端之间共享状态.一旦我的包含注释的商店被初始化,我就可以将其序列化并将其从服务器发送到客户端,在那里可以轻松恢复.
问题是填充我的商店的最佳方式是什么.在过去的几天里,我一直在谷歌搜索,我遇到了一些策略,考虑到React的这个功能被"提升"多少,这些策略看起来都不是很好.
在我看来,最简单的方法是在实际渲染开始之前填充我的所有商店.这意味着在组件层次结构之外的某个地方(例如,挂钩到我的路由器).这种方法的问题是我必须两次定义页面结构.考虑一个更复杂的页面,例如一个包含许多不同组件的博客页面(实际的博客帖子,评论,相关帖子,最新帖子,推特流......).我必须使用React组件设计页面结构,然后在其他地方我必须定义为当前页面填充每个所需存储的过程.这似乎不是一个很好的解决方案.不幸的是,大多数同构教程都是以这种方式设计的(例如,这个伟大的通量教程).
React-async.这种方法很完美.它让我只需在每个组件的特殊函数中定义如何初始化状态(无论是同步还是异步),并在层次结构呈现为HTML时调用这些函数.它的工作方式是在状态完全初始化之前不会呈现组件.问题是它需要Fibers,据我所知,这是一个改变标准JavaScript行为的Node.js扩展.虽然我非常喜欢这个结果,但在我看来,我们并没有找到解决方案,而是改变了游戏规则.而且我认为我们不应该被迫这样做来使用React.js的这个核心功能.我也不确定这个解决方案的一般支持.是否可以在标准Node.js虚拟主机上使用Fiber?
我自己在思考一点.我没有真正想过通过实现细节,但一般的想法是我会以类似于React-async的方式扩展组件,然后我会在根组件上重复调用React.renderComponentToString().在每次传递过程中,我会收集扩展回调,然后在传递和传递中调用它们来填充商店.我将重复此步骤,直到填充当前组件层次结构所需的所有存储.有很多事情需要解决,我对性能特别不确定.
我错过了什么?还有其他方法/解决方案吗?现在我正在考虑采用react-async/fiber方式,但我并不完全确定它,如第二点所述.
关于GitHub的相关讨论.显然,没有官方方法甚至解决方案.也许真正的问题是如何使用React组件.像简单的视图层(几乎是我的建议第一)或像真正的独立和独立组件?
我在我的JavaScript应用程序中使用ES6模块.源代码是用webpack和babel编译的.这是文件的缩短版本,这会给我带来麻烦:
export const JUST_FORM = 0;
export const AS_PAGE = 1;
console.log(AS_PAGE); // **
export default function doSomething(mode = AS_PAGE) {
console.log(mode);
console.log(JUST_FORM);
}
Run Code Online (Sandbox Code Playgroud)
我正如您期望的那样使用此功能.
import doSomething, { AS_PAGE } from './doSomething'
console.log(AS_PAGE);
doSomething();
Run Code Online (Sandbox Code Playgroud)
当我运行的应用程序,它打印三次undefined且仅一次的预期值AS_PAGE也就是console.log标记**.但是,这是最后打印的!它表明:
AS_PAGE当用作doSomething函数`的默认参数时,常量在定义函数时未定义.JUST_FORM当常量没有定义doSomething被调用.AS_PAGE明确的导入时没有定义的常量.显然,这里发生的事情是只有default导出被解析和评估,文件的其余部分将被忽略,直到稍后.我在我的应用程序中的几个不同位置导入此文件(此时此刻非常大),并且在某些时候这些值实际上可用.从控制台输出来看,这是时间问题,但它可能有不同的原因.显然,我在所有地方都以完全相同的方式进口.
无论如何,我已经编写了我的整个应用程序,假设一旦我导入了一些东西,它立即可用,我可以在我的代码中使用它.我(简要地)阅读了ES6模块应该如何工作,我没有找到任何可以证明这个假设错误的东西.它一直在努力.
另请注意,当我运行它webpack-dev-server或将其编译为单个包时,行为是相同的.
这种行为是否真的正确?可能有什么责任呢?
我正在开发一个SBT/Scala Web项目,我想利用ES6功能和前端JavaScript层的新模块语法.SBT有自己的构建系统,我设法调整现有的sbt插件来运行webpack来使用babel构建我的JS文件.目前的解决方案有点混乱,但它的工作原理和生活在sbt构建系统中.
问题是它很慢.对于每次更改,都会创建一个新的webpack实例,它会从头开始完全编译所有内容.
我知道我可以跳出sbt构建系统,只是为了开发阶段,分别使用webpack来观察和重建我的文件.但在我这样做之前,我想知道是否有一些方法可以加快webpack构建过程.
我检查了文档,在我看来,任何可用的缓存只在内存中处理,这不适用于我的情况.或者是否有某种文件缓存可以在单独运行的webpack构建之间存活?例如,我的所有npm依赖项都不会在大多数时间内更改,因此它们可以编译一次,缓存然后只包含...
在Spring MVC中,很容易将请求参数绑定到处理请求的方法参数.我只是用@RequestParameter("name").但是我可以对请求属性执行相同的操作吗?目前,当我想访问请求属性时,我必须执行以下操作:
MyClass obj = (MyClass) request.getAttribute("attr_name");
Run Code Online (Sandbox Code Playgroud)
但我真的想用这样的东西代替:
@RequestAttribute("attr_name") MyClass obj
Run Code Online (Sandbox Code Playgroud)
不幸的是,它没有这种方式.我可以以某种方式扩展Spring功能并添加我自己的"绑定器"吗?
编辑 (我想要实现的目标):我将当前登录的用户存储在请求属性中.因此,每当我想访问当前登录的用户(这几乎都在每个方法中)时,我必须编写这个额外的行user = (User) request.getAttribute("user");.我想尽量缩短它,最好将它作为方法参数注入.或者,如果您知道如何通过拦截器和控制器传递某些东西,我会很高兴听到它.
我知道如何在使用普通的Django Forms时设置自己的自定义错误消息.但是基于现有模型的Django Form呢?考虑以下模型和形式:
Class MyModel(models.Model):
name = models.CharField(max_length='30')
Class MyForm(forms.ModelForm):
Class Meta:
model = MyModel
Run Code Online (Sandbox Code Playgroud)
如果我创建此类表单并尝试发布,则会显示消息"此字段是必填的".但是如何改变呢?当然我可以这样做:
Class MyForm(forms.ModelForm):
model = forms.CharField(error_messages = {'required': "something..."})
Class Meta:
model = MyModel
Run Code Online (Sandbox Code Playgroud)
但根据文档,不会保留max_length属性,我必须将其显式写入表单定义.我认为Model Forms的目的是避免两次编写相同的代码.因此,必须有一些简单的方法来更改自定义错误消息,而无需重写整个表单.基本上,如果我的消息看起来像"字段'名称'是必需的",那对我来说就足够了.
请帮忙.
根据Google App Engine文档,在使用High Replication数据存储区时,写入一个实体组的速度限制为每秒一次.所以...
我正在Intellij Idea中开发一个JavaScript/React应用程序,我正在webpack-dev-server逐步构建我的文件.这意味着开发服务器正在监视文件,如果文件发生更改,则webpack重建它.很标准的场景.
不幸的是,webpack有时会决定忽略某些文件.我可以随心所欲地改变它们,但webpack什么都不做.我无法确定哪些文件被忽略的模式.这是武断的.有时我只是创建一个新文件并webpack忽略它.
有趣的是,只有当我使用Intellij Idea执行保存时才会发生这种情况.如果我在另一个编辑器(例如vim)中打开该文件并保存它,则会正确地重建该文件.实际上,简单touch file.js就足以触发重建.
我猜Intellij Idea如何保存文件有问题.有任何想法吗?
我知道这已经发布但很久以前,所以我再次询问是否有变化:有没有办法在Eclipse文本编辑器中设置行间距/行高?默认设置对我来说似乎不太可读 - 看到区别:http://img522.imageshack.us/img522/3315/eclipseyh.png(通常Eclipse怪异地渲染字体,它们在gvim中看起来好多了).
我已经阅读了提示,我可以手动编辑某些字体并修改其属性,但这对于这么简单的任务来说似乎有点过于复杂.
Flux的目标之一是通过减少疯狂纠结的依赖关系来使应用程序更具可预测性.使用Dispatcher,您可以定义更新商店的严格顺序.这创建了一个很好的树依赖层次结构 这就是理论.考虑以下情况:
我有一场比赛.位于层次结构顶部的商店是StateStore,它只保存当前游戏状态,即播放,暂停,结束.它通过PAUSE或RESUME等操作进行更新.所有其他商店都依赖于这个.因此,当商店处理某种更新操作(即MOVE_LEFT)时,它首先检查StateStore,如果游戏暂停或结束,则忽略该操作.
现在让我们说有一个动作会导致游戏结束.它更新了一些商店,商店决定游戏不应该继续("游戏角色向左移动并陷入陷阱").所以StateStore中的州应该改为结束.我怎么做?
从理论上讲,它应该是这样的:
不幸的是,其他商店也需要访问StateStore来检查当前的游戏状态,看它是否应该更新(即游戏没有暂停).他们显然相互依赖.
可能的解决方案:
你怎么看?
我在我的应用程序中使用了React + Redux + Reselect + Immutable.js的最终组合.我喜欢重新选择的想法,因为它让我保持我的状态(由减速器维护)尽可能简单.我使用一个选择器来计算我需要的实际状态,然后将其提供给React组件.
这里的问题是,一次reducers的一个小变化会导致选择器重新计算整个派生输出,结果整个React UI也会更新.我的纯组件不起作用.这很慢.
典型示例:我的数据的第一部分来自服务器,基本上是不可变的.第二部分由客户端维护,并使用redux操作进行变更.它们由单独的减速器维护.
我使用选择器将两个部分合并到一个记录列表中,然后传递给React组件.但显然,当我在其中一个对象中更改单个内容时,将重新生成整个列表并创建新的Records实例.UI完全重新渲染.
显然每次运行选择器并不是完全有效但仍然相当快,我愿意做出这种交易(因为它确实使代码更简单,更清晰).问题是实际渲染很慢.
我需要做的是将新选择器输出与旧选择器输出深度合并,因为Immutable.js库足够聪明,不会在没有任何更改时创建新实例.但由于选择器是无法访问先前输出的简单功能,我想这是不可能的.
我认为我目前的做法是错误的,我想听听其他想法.
可能的方法是在这种情况下摆脱重新选择并将逻辑移动到reducers的层次结构中,该层次结构将使用增量更新来维持所需的状态.
flux ×2
javascript ×2
reactjs ×2
webpack ×2
babel ×1
babeljs ×1
django ×1
eclipse ×1
ecmascript-6 ×1
editor ×1
forms ×1
immutable.js ×1
java ×1
node.js ×1
reactjs-flux ×1
redux ×1
reselect ×1
spring ×1
spring-mvc ×1