React.js数据流范式-data.props、state和JSX如何有益



我正在使用React,并创建了一个包含4个组件的小页面(React类,首选术语是什么?我在这篇文章中称它们为组件):

组件分解

  • 一个父母"应用程序";包含并管理其他组件的组件
  • a";形式";允许用户与页面交互的组件
  • a";字符串视图"将表单中的输入显示为文本的组件
  • a";"视觉视图";(我知道,坏名字…)组件,它解释字符串视图并执行操作来调整视觉效果

数据流

使用状态和道具的这些组件的通信如下:

  1. 表单有onChange处理程序,可以将新状态传递给应用程序
  2. 应用程序将状态数据集中到字符串视图
  3. 字符串视图更新并将更新后的状态传递给应用程序
  4. 应用程序将新的状态数据集中到Visual View
  5. 最后,Visual View现在根据新状态进行更新

示例代码

var App = React.createClass({
handleFormChange: function(formData) {
this.setState({formData:formData});
},  
handleStringChange: function(stringData) {
this.setState({stringData:stringData});
},
render: function() {
return (
<div className="app">
<FormView onFormChange={this.handleFormChange}/>
<StringView formData={this.state.formData} onStringChange={this.handleStringChange}/>
<VisualView stringData={this.state.stringData}/>
</div>
);
}
});
var FormView = React.createClass({
handleFormChange: function(e) {
this.props.onFormChange(e.target.value);
}
render: function() {
return(
<div className="formView">
<select onChange={this.handleFormChange}>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
);
}
});
var StringView = React.createClass({
componentDidUpdate: function() {
this.props.onStringChange({newString:'newStringState'});
},
render: function() {
this.props.formData;
// process formData and update state
return (
<div className="stringView">
{this.props.formData}
</div>
);
}
});
var VisualView = React.createClass({
render: function() {
var selection = this.props.stringData,
output = '';
if (selection === 1) {
output = 'Hooray, 1!';
} else {
output = 'Yes! 2!';
}
return (
<div className="stringView">
{output}
</div>
);
}
});

问题

  1. 这是React试图强制执行的正确数据流范式吗(组件只与父母对话,而不是与兄弟姐妹对话)
  2. 与我用普通JavaScript写这篇文章的方式相比,这似乎受到了极大的限制。我是不是错过了大局?这种数据流范式是为了防止未来的问题(如果是,哪些问题?任何无法用规范的JavaScript解决的问题?),还是我缺少了其他目的
  3. 我得到了很多重复的函数名称(例如handleFormChange,它在应用程序和窗体视图中使用),有没有一个好的方法可以区分这些名称?或者,是否需要跨组件重复使用函数名称
  4. 当组件真正构建时,JSX的东西会被转换成真正的JavaScript。使用JSX有优势吗?用已经转换过的JavaScript编写组件会有优势吗

首先,我认为调用"components"是可以的,我见过很多人这样调用。我将在下面回答您的问题,我认为这样做更有意义。

当组件真正构建时,JSX的东西会被转换成真正的JavaScript。使用JSX有优势吗?用已经转换过的JavaScript编写组件会有优势吗?

JSX有点混合了JavaScript和HTML,因此,它使您的代码"友好"。您将创建您的组件,并将它们作为HTML标记"调用"。下面您可以看到编写JSX和纯JavaScript之间的区别。

return <div className="my-component"><p>Awesome</p></div>;
return ReactDOM.div({
className: 'my-component'
}, ReactDOM.p({}, "Awesome"));

我不认识你,但我会厌倦写这么多代码来呈现一个带有段落的div。

你可以在这里查看使用它的更多好处:

https://hchen1202.gitbooks.io/learning-react-js/content/benefits_of_jsx.html

我得到了很多重复的函数名称(例如handleFormChange,它在应用程序和表单视图中使用),有什么好的方法可以区分这些名称吗?或者,是否需要跨组件重复使用函数名称?

这还不错,而且,你的应用程序是一个"演示"的应用程序,如果它是"真实的"应用程序,它会有一些更好的组件名称(即<FormView>将是<ContactForm>),也许你的方法名称会有所不同。但它一点也不坏。例如,在<ContactForm>内部,您可以将submit处理程序调用为onSubmit,但在外部(传递的prop),您可以调用onContactFormSubmit,或者以更语义的方式调用onContactFormFilled

如果你的应用程序开始增长,并且在同一个组件中重复了很多东西(<App>就是这样),你可能会尝试拆分你的组件,因此,你的每个组件都会"知道"一个"域",而且它看起来不会有很多重复的东西。

这是React试图强制执行的正确数据流范式吗(组件只与父母对话,而不是与兄弟姐妹对话)?

首先,React不会"强制"任何东西,正如一些人所说,React是MVC中的"v",因此,您的"表示"层被描述为组件,数据可以按照您想要的方式流动。但是,当你说"组件只与父母交谈,而不是与兄弟姐妹交谈"时,你就明白了这一点,因为当你有多个组件时,这是你可以在组件之间"交流"的方式。由于组件看不到其同级,因此需要有人来协调这种通信,在这种情况下,这是父级的工作。

还有其他方法可以让组件相互"对话"(即使用refs),但IMO认为,有一个父级来协调是最可靠(也更容易测试)的方法。

与我用普通JavaScript写这篇文章的方式相比,这似乎受到了极大的限制。我是不是错过了大局?这种数据流范式是为了防止未来的问题(如果是,哪些问题?任何无法用规范的JavaScript解决的问题?),还是我缺少了其他目的?

我决定把它作为最后一个答案来总结一些事情。

IMO,React非常棒,你开始把你的"逻辑"放在正确的位置(一个组件),你可以把东西组合起来,让你的页面正常工作(我的意思是它被正确地编排)。

React还使您更容易"思考"如何构建接口。这篇Pete Hunt的博客文章太棒了,你应该看看:

https://facebook.github.io/react/docs/thinking-in-react.html

如果您使用纯JavaScript编写代码,则必须以某种方式处理DOM(即使用模板引擎),并且您的代码最终会将DOM操作应用程序逻辑混合。React只是为你抽象了一下。您只能关心演示内容。另一个优点是,当所有东西都是一个组件时,您可以重用这些组件,不管它们位于哪里。如果您正确地传递道具,您的组件将按预期工作。

我知道写这些组件似乎是详尽无遗的,但当你开始写更多的组件时,你开始看到很多好处。其中之一就是不再关心如何显示数据(不再连接HTML字符串或调用模板函数)。另一个原因是很容易"拆分"接口,这使得代码更容易维护(使用纯JavaScript时这并不简单)。

老实说,你编写的这个应用程序非常简单,你可能看不到使用React构建它的很多优点。我认为你应该尝试创建一个更"复杂"的应用程序,并将其与普通JavaScript进行比较。我所说的"复杂"是指"用户界面"的复杂性。例如,创建一个允许用户提交多个"人员"的表单。"人"应该有"名字"和多个"宠物"(也有名字)。您将看到在这种情况下处理"添加"one_answers"删除"操作有多难,React处理这种事情有多容易。

我想就是这样,我希望你和React"点击"。它改变了我对如何创建复杂用户界面的想法。

最新更新