React官网的RECENT POSTS阅读
??写在开头
??为什么要使用React目前已经有很多的
同时创建了JSX,它是JavaScript的语法扩展。如果比如原生的JavaScript,你更喜欢HTML的可读性,就使用它吧! 不能再简单的响应式数据更新当你的应用数据随着时间变化时,React表现是十分耀眼! 在传统的JavaScript应用中,你需要关注哪些数据变化了并且命令式的改变DOM的状态,以便保持视图和数据的一致。甚至通过指令和数据来提供了一种声明式界面的AngularJS,也是通过绑定需要的函数来手动更新DOM节点。 React采用不同的方法:
HTML仅仅只一个开始由于React有着自己的轻量级的文本表达式,我们可以做一些更酷的事情:
??React v0.3.3我们将在React v0.4中新增了许多中西,但是与此同时我们发布了React v0.3.3。这个版本解决了人们在使用中遇到的问题,并且使我们的工具更加容易使用。 React允许反复使用同一个DOMNode渲染不同的组件。
??New in React v0.4: Prop Validation and Default Values我们收到关于 Validation在使用props之前,我们经常对props的某些参数进行某些特殊的处理,例如:需要确定这些属性是否是特定的类型、需求限定某些值、某些参数的成分是必须的。这些验证我们都可以在render里面处理,但是这回使render显得臃肿! 现在, React.createClass({ propTypes: { // An optional string prop named "description". description: React.PropTypes.string,// A required enum prop named "category". category: React.PropTypes.oneOf(['News','Photos']).isRequired,// A prop named "dialog" that requires an instance of Dialog. dialog: React.PropTypes.instanceOf(Dialog).isRequired },... }); Default Values在以往的例子里面,我们经常看到以下代码: React.createClass({ render: function() { var value = this.props.value || 'default value'; return <div>{value}</div>; } }); 如果对几个穿插在几个不同组件的 React.createClass({ getDefaultProps: function() { return { value: 'default value' }; } ... }); 在render之前,我们使用这些函数进行处理(我们也会在
??React v0.4.1
React
JSXTransformer改良环境检测机制,使其能运行在非浏览器环境。
??Use React and JSX in Python Applications今天我们很高兴的宣布 Usage:show me codefrom react import jsx # For multiple paths,use the JSXTransformer class. transformer = jsx.JSXTransformer() for jsx_path,js_path in my_paths: transformer.transform(jsx_path,js_path) # For a single file,you can use a shortcut method. jsx.transform('path/to/input/file.jsx','path/to/output/file.js') Django:support the pip#install $ pip install PyReact #use PIPELINE_COMPILERS = ( 'react.utils.pipeline.JSXCompiler',) React PageJordan Walke 实现了一个完整的 为什么使用服务端渲染?
服务端渲染是如何进行的?
?? React v0.5Changelog
JSX
?? React v0.9 [RC]Upgrade Notes我们 <div> Monkeys: {listOfMonkeys} {submitButton} </div> 0.8- React.DOM.div(null," Monkeys: ",listOfMonkeys,submitButton ) 0.9+ React.DOM.div(null,"Monkeys:"," ",submitButton ) 相信这个新特性会非常有空,可以有效减少匆忙之中带来的非期待的空格。 如果你希望保留 后面紧跟换行文本节点 后面的空格,那么你可以在 ?? The Road to 1.0 (2014-03-28)我们在去年春天发布了 我们在1.0中主要的目的是阐明我们的消息模式,并且聚焦在一个与我们目的相关的API上面进行处理。为了完成这个目的,我们清除一些已经遇到的不友好的模式,真正的帮助开发者写出更好的代码。 ES6在我们正式推出 class MyComponent extends React.Component { render() { ... } } 其他一些
Context尽管我们没有在文档中提及过
?? React v0.11getDefaultProps从React0.11开始, Rendering to null自从React发布以来,开发者基本都遇到过 render nothing 的情况。通常是返回一个空 // Before render: function() { if (!this.state.visible) { return <span/>; } // ... } // After render: function() { if (!this.state.visible) { return null; } // ... } JSX Namespacing在 // Before var UI = require('UI'); var UILayout = UI.Layout; var UIButton = UI.Button; var UILabel = UI.Label; render: function() { return <UILayout><UIButton /><UILabel>text</UILabel></UILayout>; } // After var UI = require('UI'); render: function() { return <UI.Layout><UI.Button /><UI.Label>text</UI.Label></UI.Layout>; } Improved keyboard event normalization根据DOM3,React键盘事件包含了一个标准化的 handleKeyDown: function(e) { if (e.key === 'Enter') { // Handle enter key } else if (e.key === ' ') { // Handle spacebar } else if (e.key === 'ArrowLeft') { // Handle left arrow } }
?? Flux: Actions and the Dispatcher
比如一个完整的框架, Where the Dispatcher Fits in the Flux Data Flow
Actions and ActionCreators无论是用户进行界面操作还是接口返回的新数据进入系统的时候,这些数据将会被打包送入一个 不同的 使 Why We Need a Dispatcher随着应用的壮大,不同
更者, Problems arise,however,if we have circular dependencies. That is,if Store A needs to wait for Store B,and Store B needs to wait for Store A,we could wind up in an endless loop. The dispatcher now available in the Flux repo protects against this by throwing an informative error to alert the developer that this problem has occurred. The developer can then create a third store and resolve the circular dependency. ??Introducing React Elements
New Terminolog我们为了使新用户更简单的了解 Creating a ReactElement我们提供一个API来创建 var reactElement = React.createElement(type,props,children);
var div = React.createFactory('div'); var reactDivElement = div(props,children);
{ type : string | class,props : { children,className,etc. },key : string | boolean | number | null,ref : string | null } Upgrading to 0.12React With JSX 如果你使用 // If you use node/browserify modules make sure // that you require React into scope. var React = require('react');
var MyComponent = React.createClass(...); var MyOtherComponent = React.createClass({ render: function() { return <MyComponent prop="value" />; } }); React Without JSX 在不使用 var MyComponentClass = React.createClass(...); var MyComponent = React.createFactory(MyComponentClass); // New step var MyOtherComponent = React.createClass({ render: function() { return MyComponent({ prop: 'value' }); } });
var MyDOMComponent = React.createClass({ render: function() { return React.DOM.div({ className: 'foo' }); // still ok } }); The Next Step: ES6 Classes在v0.12版本后,我们的工作将转向 export class MyComponent { render(){ ... } }; ??Deprecating JSTransform and react-tools随着 Other Deprecationsesprima-fb ECMAScript解析器 JSXTransformer JSXTransformer is another tool we built specifically for consuming JSX in the browser. It was always intended as a quick way to prototype code before setting up a build process. It would look for <script> tags with type="text/jsx" and then transform and run. This ran the same code that react-tools ran on the server. ??ReactDOM.render and the Top Level React API在 ReactDOM.render(reactElment,domContainerNode) 这需要你提供一个额外的DOM容器。 当把 ReactDOM.unmountComponentAtNode(domComtainerNode)
Object Oriented Updates如果你调用 ReactDOM.render(<App locale="en-US" userID={1} />,container); // props.userID == 1 // props.locale == "en-US" ReactDOM.render(<App userID={2} />,container); // props.userID == 2 // props.locale == undefined ??!? 在面向对象编程中,所有的状态依赖实例存在,通过控制状态的改变控制应用变化。如果你在一个使用面向对象API的app里面使用 对此我们提供了一个辅助函数
class ReactComponentRenderer { constructor(klass,container) { this.klass = klass; this.container = container; this.props = {}; this.component = null; } replaceProps(props,callback) { this.props = {}; this.setProps(props,callback); } setProps(partialProps,callback) { if (this.klass == null) { console.warn( 'setProps(...): Can only update a mounted or ' + 'mounting component. This usually means you called setProps() on ' + 'an unmounted component. This is a no-op.' ); return; } Object.assign(this.props,partialProps); var element = React.createElement(this.klass,this.props); this.component = ReactDOM.render(element,this.container,callback); } unmount() { ReactDOM.unmountComponentAtNode(this.container); this.klass = null; } }
class ReactVideoPlayer { constructor(url,container) { this._container = container; this._url = url; this._isPlaying = false; this._render(); } _render() { ReactDOM.render( <VideoPlayer url={this._url} playing={this._isPlaying} />,this._container ); } get url() { return this._url; } set url(value) { this._url = value; this._render(); } play() { this._isPlaying = true; this._render(); } pause() { this._isPlaying = false; this._render(); } destroy() { ReactDOM.unmountComponentAtNode(this._container); } } ??React Components,Elements,and Instances
Managing the Instances如果你是初学者,你也许开始是和 在传统的UI模块中,由你来控制创建和销毁组件实例。栗:如果一个 class Form extends TraditionalObjectOrientedView { render() { // Read some data passed to the view const { isSubmitted,buttonText } = this.attrs; if (!isSubmitted && !this.button) { // Form is not yet submitted. Create the button! this.button = new Button({ children: buttonText,color: 'blue' }); this.el.appendChild(this.button.el); } if (this.button) { // The button is visible. Update its text! this.button.attrs.children = buttonText; this.button.render(); } if (isSubmitted && this.button) { // Form was submitted. Destroy the button! this.el.removeChild(this.button.el); this.button.destroy(); } if (isSubmitted && !this.message) { // Form was submitted. Show the success message! this.message = new Message({ text: 'Success!' }); this.el.appendChild(this.message.el); } } } 上面的伪复合UI代码(或者增加更多)都是按照面向对象的方式使用库,就像 比起上述, Elements Describe the Tree为解决上述问题,
一个 DOM Elements 当 { type: 'button',props: { className: 'button button-blue',children: { type: 'b',props: { children: 'OK!' } } } } ? <button class='button button-blue'> <b> OK! </b> </button> 对于 最重要的一点还是
Component Elements 然后 { type : Button,props : { color : "blue",children : "OK!",} } 这是
这个特性可以让你创建一个 const DangerButton = ({ children }) => ({ type: Button,props: { color: 'red',children: children } }); 你可以混合搭配 const DeleteAccount = () => ({ type: 'div',props: { children: [{ type: 'p',props: { children: 'Are you sure?' } },{ type: DangerButton,props: { children: 'Yep' } },{ type: Button,props: { color: 'blue',children: 'Cancel' } }] }); 或者你使用 const DeleteAccount = () => ( <div> <p>Are you sure?</p> <DangerButton>Yep</DangerButton> <Button color='blue'>Cancel</Button> </div> ); 这种混合和匹配有助于降低组件之间的耦合度,因此它们完全可以通过一下的结构同时表达is-a和has-a的关系
Components Encapsulate Element Trees 当 当看到这个 { type: Button,props: { color: 'blue',children: 'OK!' } }
{ type: 'button',props: { children: 'OK!' } } } }
前面提到的 const Form = ({ isSubmitted,buttonText }) => { if (isSubmitted) { // Form submitted! Return a message element. return { type: Message,props: { text: 'Success!' } }; } // Form is still visible! Return a button element. return { type: Button,props: { children: buttonText,color: 'blue' } }; }; 以上,对于
返回的元素树包括描述 我们使 我们使用 Components Can Be Classes or Functions // 1) As a function of props const Button = ({ children,color }) => ({ type: 'button',props: { className: 'button button-' + color,props: { children: children } } } }); // 2) Using the React.createClass() factory const Button = React.createClass({ render() { const { children,color } = this.props; return { type: 'button',props: { className: 'button button-' + color,children: { type: 'b',props: { children: children } } } }; } }); // 3) As an ES6 class descending from React.Component class Button extends React.Component { render() { const { children,props: { children: children } } } }; } }
A functional component is less powerful but is simpler,and acts like a class component with just a single render() method. Unless you need features available only in a class,we encourage you to use functional components instead. Top-Down Reconciliation ReactDOM.render({ type: Form,props: { isSubmitted: false,buttonText: 'OK!' } },document.getElementById('root')); 你当运行上述代码的时候, // React: You told me this... { type: Form,buttonText: 'OK!' } } // React: ...And Form told me this... { type: Button,props: { children: 'OK!',color: 'blue' } } // React: ...and Button told me this! I guess I'm done. { type: 'button',props: { children: 'OK!' } } } }
Summary
一个组件的申明有几个不同的方式: An instance is what you refer to as this in the component class you write. It is useful for storing local state and reacting to the lifecycle events.(实例就是对组件类中this的引用。) 最后,创建 ??(A => B) !=> (B => A)文档里面对于
你如果不相信,可以试试使用准确的 class Component extends React.Component { componentWillReceiveProps(nextProps) { console.log('componentWillReceiveProps',nextProps.data.bar); } render() { return <div>Bar {this.props.data.bar}!</div>; } } var container = document.getElementById('container'); var mydata = {bar: 'drinks'}; ReactDOM.render(<Component data={mydata} />,container); ReactDOM.render(<Component data={mydata} />,container); 以上代码 为了理解为什么会这样,我们需要想想会发生什么。在初始渲染和两次后续更新之间数据可能已经被改变了,如果代码像下面这样执行: var myData = { bar: 'drinks' }; ReactDOM.render(<Component data={myData} />,container); myData.bar = 'food'; ReactDOM.render(<Component data={myData} />,container); myData.bar = 'noise'; ReactDOM.render(<Component data={myData} />,container); 数据没有改变,但React并没有办法知道。因此, 你可能会认为,
由于语言的限制,有时我们不可能实现真正意义上相等的语义。在这种情况下, 这样一来,实现 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |