Because some time ago, I did a little research on Nativejs launched by dcloud and reactNative launched by facebook. Because the research is very simple, it only represents my personal point of view and talks about some feelings about using these two products.
Starting with dcloud's Nativejs, we should start with his IDE editor. The Hbuilder they launched is really very useful, and it is really fast to write code. Previously, I thought sublime was easy to use, but when you use Hbuilder, sublime would be inferior. After using Hbuilder for a period of time, I feel that the only drawback is that the files obtained from the git pull library will not be refreshed from time to time.
When talking about using Hbuilder to develop an APP. We can download its official case. The development and learning cost is very low, and it is very fast, because it is used for html5 and some css development. Let's take a look at some of their native usage in js encapsulation:
Http://www.html5plus.org/doc/zh_cn/android.html #
Ios: http://www.html5plus.org/doc/zh_cn/ios.html
Covers most of the APP development interfaces.
Nativejs uses the openWindow method to open a window, similar to creating a new Webview and closing a window. It is similar to closing a Webview. Value transfer between windows. You can use
Extras :{
... // Custom extension parameter, which can be used to process cross-page data transfer
},
This method. You can also trigger custom events. OpenWindow solves the problem of returning an endless loop in history in h5.
However, I have some problems with using it because many codes are written in html5. When some functions can be implemented using html5 and its encapsulated js, we will unconsciously use the old html5 solution to solve some problems, which eventually leads to lower APP efficiency. To put it bluntly, apps developed with Hbuilder are no different from those developed with APPCan and phoneGap. They are all developed with hybrid.
But when facebook launched reactNative, it quickly got angry! Many Android developers around me started to study js. They started to study reactNative, because reactNative can be used for Android and IOS development across platforms, and the efficiency is not low!
Why! Because the reactNative logic is written in js, but the UI is all native, he renders js into android and ios code.
However, the learning Cost of reactNative is relatively high. Let's take a look at his document. We need to set up the environment. We need to install nodejs, java Runtime Environment, and android SDK on Windows 7. It uses the brand new syntax jsx. Before learning reactNative, you 'd better learn reactjs first. I personally think a blog written by Ruan Yifeng is not bad.
Install
The React installation package can be downloaded from the official website. However, React Demos already comes with the React source code. You don't need to install it. Just copy this library to your hard disk.
$ Git clone git@github.com: ruanyf/react-demos.git
If you have not installed git, download the zip package directly.
The 12 examples to be explained below are in each Demo sub-directory. Each directory has an index.html file, which can be opened in a browser (double-click in most cases) to see the effect immediately.
It should be noted that React can be run in the browser or on the server, but this tutorial only involves the browser. On the one hand, The React syntax is the same, and the server usage is slightly different from that of the browser. Demo13 is an example of server first screen rendering. If you are interested, you can view the source code by yourself.
I. HTML template
The source code of the web page using React is roughly as follows.
<! DOCTYPE html>
<Html>
<Head>
<Script src = "../build/react. js"> </script>
<Script src = "../build/react-dom.js"> </script>
<Script src = "../build/browser. min. js"> </script>
</Head>
<Body>
<Div id = "example"> </div>
<Script type = "text/babel">
// ** Our code goes here! **
</Script>
</Body>
</Html>
The above code has two points to note. First, the type attribute of the last <script> tag is text/babel. This is because React's unique JSX syntax is incompatible with JavaScript. Type = "text/babel" must be added wherever JSX is used ".
Second, the above code uses a total of three libraries: react. js, react-dom.js and Browser. js, they must be loaded first. React. javaScript is the core library of React, react-dom.js is to provide DOM-related functions, Browser. js converts JSX syntax into JavaScript syntax, which consumes a lot of time. It should be placed on the server when it is launched.
$ Babel src -- out-dir build
The above command can convert the syntax of the js file in the src subdirectory, and put all the transcoded files in the build subdirectory.
II. ReactDOM. render ()
ReactDOM. render is the most basic method of React. It is used to convert a template into an HTML language and insert a specified DOM node.
ReactDOM. render (
<H1> Hello, world! </H1>,
Document. getElementById ('example ')
);
The above code inserts an h1 title into the example node (view demo01). The running result is as follows.
III. JSX syntax
In the code in the previous section, the HTML language is directly written in the JavaScript language without any quotation marks. This is the JSX syntax, which allows mixed HTML and JavaScript writing (view Demo02 ).
Var names = ['Alice ', 'Emily', 'Kate '];
ReactDOM. render (
<Div>
{
Names. map (function (name ){
Return <div> Hello, {name }! </Div>
})
}
</Div>,
Document. getElementById ('example ')
);
The code above demonstrates the basic syntax rules of JSX: When an HTML tag (starting with <) is encountered, it is parsed using HTML rules. When a code block (starting with {) is encountered, it is parsed using JavaScript rules. The running result of the above code is as follows.
JSX allows you to insert JavaScript variables directly in the template. If this variable is an array, all the members of this array are displayed (view demo03 ).
Var arr = [
<H1> Hello world! </H1>,
<H2> React is awesome ];
ReactDOM. render (
<Div> {arr} </div>,
Document. getElementById ('example ')
);
The arr variable of the code above is an array, and JSX adds all its members to the template. The running result is as follows.
IV. Components
React allows code to be encapsulated into a component, and then insert the component into the webpage like inserting a common HTML tag. The React. createClass method is used to generate a component class (view demo04 ).
Var HelloMessage = React. createClass ({
Render: function (){
Return }
});
ReactDOM. render (
<HelloMessage name = "John"/>,
Document. getElementById ('example ')
);
In the code above, the variable HelloMessage is a component class. When the template is inserted with <HelloMessage/>, an instance of HelloMessage is automatically generated (the following "component" refers to the instance of the component class ). All component classes must have their own render method for output components.
Note: The first letter of the component class must be in uppercase; otherwise, an error is returned. For example, HelloMessage cannot be written as helloMessage. In addition, the component class can only contain one top-level tag. Otherwise, an error is returned.
Var HelloMessage = React. createClass ({
Render: function (){
Return Hello {this. props. name}
</H1> <p>
Some text
</P>;
}
});
The above code will report an error because the HelloMessage component contains two top-level labels: h1 and p.
The component usage is exactly the same as that of the native HTML tag. Attributes can be added at will. For example, <HelloMessage name = "John"> indicates that the HelloMessage component adds a name attribute with the value of John. The attributes of a component can be obtained on the this. props object of the component class. For example, the name attribute can be read through this. props. name. The running result of the above code is as follows.
When adding component attributes, you must note that the class attributes must be written as className and the for attributes must be written as htmlFor, because class and for are reserved words of JavaScript.
5. this. props. children
This. Attributes of the props object correspond to the attributes of the component one by one, but an exception is the this. props. children attribute. It indicates all child nodes of the component (view demo05 ).
Var NotesList = React. createClass ({
Render: function (){
Return (
<Ol>
{
React. Children. map (this. props. children, function (child ){
Return <li> {child} </li>;
})
}
</Ol>
);
}
});
ReactDOM. render (
<NotesList>
<Span> hello </span>
<Span> world </span>
</NotesList>,
Document. body
);
The NoteList component of the code above has two span subnodes which can be read through this. props. children. The running result is as follows.
Note that this. props. there are three possible values for children: undefined if the current component does not have a subnode; object if there is a subnode, and array if there are multiple subnodes. Therefore, be careful when processing this. props. children.
React provides a tool method React. Children to handle this. props. children. We can use React. Children. map to traverse subnodes without worrying about whether the data type of this. props. children is undefined or object. For More React. Children methods, see the official documentation.
6. PropTypes
The component attributes can accept any value, including strings, objects, and functions. Sometimes, we need a mechanism to verify that the parameters provided by others when using components meet the requirements.
The PropTypes attribute of the component class is used to verify whether the attributes of the component instance meet the requirements (view demo06 ).
Var MyTitle = React. createClass ({
PropTypes :{
Title: React. PropTypes. string. isRequired,
},
Render: function (){
Return }
});
The above Mytitle component has a title attribute. PropTypes tells React that this title attribute is required and its value must be a string. Now, we set the value of the title attribute to a value.
Var data = 123;
ReactDOM. render (
<MyTitle title = {data}/>,
Document. body
);
In this way, the title attribute cannot be verified. The console displays an error message.
Warning: Failed propType: Invalid prop 'title' of type 'number' suied IED to 'mytitle', expected 'string '.
For more PropTypes settings, see the official documentation.
In addition, the getdefaproprops method can be used to set the default value of component properties.
Var MyTitle = React. createClass ({
Getdefaproprops: function (){
Return {
Title: 'Hello world'
};
},
Render: function (){
Return }
});
ReactDOM. render (
<MyTitle/>,
Document. body
);
The above code will output "Hello World ".
7. Obtain real DOM nodes
A component is not a real DOM node, but a data structure in the memory, called virtual DOM ). It becomes a real DOM only after being inserted into a document. According to The React design, all DOM changes occur on the Virtual DOM first, and then the actual changes are reflected on the real DOM. This algorithm is called DOM diff, it can greatly improve the performance of web pages.
However, sometimes you need to obtain the real DOM node from the component, then you need to use the ref attribute (view demo07 ).
Var MyComponent = React. createClass ({
HandleClick: function (){
This. refs. myTextInput. focus ();
},
Render: function (){
Return (
<Div>
<Input type = "text" ref = "myTextInput"/>
<Input type = "button" value = "Focus the text input" onClick = {this. handleClick}/>
</Div>
);
}
});
ReactDOM. render (
<MyComponent/>,
Document. getElementById ('example ')
);
In the code above, the child node of the component MyComponent has a text input box for obtaining user input. In this case, you must obtain the real DOM node. The Virtual DOM cannot obtain user input. To do this, the text input box must have a ref attribute. Then this. refs. [refName] returns this real DOM node.
Note that because the this. refs. [refName] attribute obtains the real DOM, you must wait until the Virtual DOM is inserted into the document. Otherwise, an error is returned. In the code above, by specifying the callback function for the Click event for the component, it ensures that the attribute this. refs. [refName] will be read only after the Click event occurs in the real DOM.
The React component supports many events, including Click events, KeyDown, Copy, and Scroll. For a complete list of events, see the official documentation.
8. this. state
Components inevitably need to interact with users. A major innovation of React is to regard components as a state machine, with an initial state at the beginning, and then user interaction, resulting in status changes, this triggers re-rendering of the UI (view demo08 ).
Var LikeButton = React. createClass ({
GetInitialState: function (){
Return {liked: false };
},
HandleClick: function (event ){
This. setState ({liked :! This. state. liked });
},
Render: function (){
Var text = this. state. liked? 'Like': 'Haven \'t liked ';
Return (
<P onClick = {this. handleClick}>
You {text} this. Click to toggle.
</P>
);
}
});
ReactDOM. render (
<LikeButton/>,
Document. getElementById ('example ')
);
The above code is a LikeButton component. Its getInitialState method is used to define the initial state, that is, an object. this object can be read through the this. state attribute. When a user clicks a component and the status changes, the this. setState method modifies the status value. After each modification, the this. render method is automatically called to render the component again.
Because this. props and this. state are both used to describe the features of components, confusion may occur. A simple differentiation method is that this. props represents those features that will not be changed once defined, and this. state is a feature that will change with user interaction.
IX. Forms
The content entered by the user in the form is the interaction between the user and the component, so this. props cannot be used to read (view demo9 ).
Var Input = React. createClass ({
GetInitialState: function (){
Return {value: 'Hello! '};
},
HandleChange: function (event ){
This. setState ({value: event.tar get. value });
},
Render: function (){
Var value = this. state. value;
Return (
<Div>
<Input type = "text" value = {value} onChange = {this. handleChange}/>
<P> {value} </p>
</Div>
);
}
});
ReactDOM. render (<Input/>, document. body );
In the above code, the value of the text input box cannot be read using this. props. value. Instead, you need to define a callback function for the onChange event to read the value entered by the user through event.tar get. value. The textarea, select, and radio elements all belong to this situation. For more information, see the official documentation.
10. Component lifecycle
The lifecycle of a component is divided into three states:
Mounting: The real DOM has been inserted.
Updating: being re-rendered
Unmounting: The real DOM has been removed.
React provides two processing functions for each state. The "will" function is called before it enters the state. The "did" function is called after it enters the state. There are five processing functions in three states.
ComponentWillMount ()
ComponentDidMount ()
ComponentWillUpdate (object nextProps, object nextState)
ComponentDidUpdate (object prevProps, object prevState)
ComponentWillUnmount ()
In addition, React provides two special state processing functions.
ComponentWillReceiveProps (object nextProps): called when the loaded component receives a new parameter
ShouldComponentUpdate (object nextProps, object nextState): called when the component determines whether to re-render
For more information about these methods, see the official documentation. The following is an example (view demo10 ).
Var Hello = React. createClass ({
GetInitialState: function (){
Return {
Opacity: 1.0
};
},
ComponentDidMount: function (){
This. timer = setInterval (function (){
Var opacity = this. state. opacity;
Opacity-=. 05;
If (opacity <0.1 ){
Opacity = 1.0;
}
This. setState ({
Opacity: opacity
});
}. Bind (this), 100 );
},
Render: function (){
Return (
<Div style ={{ opacity: this. state. opacity }}>
Hello {this. props. name}
</Div>
);
}
});
ReactDOM. render (
<Hello name = "world"/>,
Document. body
);
After the hello component is loaded, the code above sets a timer through the componentDidMount method. The transparency of the component is reset every 100 milliseconds, leading to re-rendering.
In addition, it is worth noting that the style attribute setting method of the component cannot be written
Style = "opacity: {this. state. opacity };"
To write
Style ={{ opacity: this. state. opacity }}
This is because the React component style is an object, so the first braces indicate that this is JavaScript syntax, and the second major parentheses indicate the style object.
11. Ajax
The component data source is usually obtained from the server through Ajax requests. You can use the componentDidMount method to set Ajax requests. After the request is successful, use this. setState method to re-render the UI (view demo11 ).
Var UserGist = React. createClass ({
GetInitialState: function (){
Return {
Username :'',
LastGistUrl :''
};
},
ComponentDidMount: function (){
$. Get (this. props. source, function (result ){
Var lastGist = result [0];
If (this. isMounted ()){
This. setState ({
Username: lastGist. owner. login,
LastGistUrl: lastGist.html _ url
});
}
}. Bind (this ));
},
Render: function (){
Return (
<Div>
{This. state. username}'s last gist is
<A href = {this. state. lastGistUrl}> here </a>.
</Div>
);
}
});
ReactDOM. render (
<UserGist source = "https://api.github.com/users/octocat/gists"/>,
Document. body
);
The above code uses jQuery to complete Ajax requests for ease of instruction. The React itself does not have any dependencies. You can use other libraries instead of jQuery.
We can even pass a Promise object into the component. Please refer to Demo12.
ReactDOM. render (
<RepoList
Promise = {$. getJSON ('https: // api.github.com/search/repositories? Q = javascript & sort = stars ')}
/>,
Document. body
);
The code above captures data from the Github API, and then uses the Promise object as an attribute to pass it to the RepoList component.
If the Promise object is in the pending state, the component displays "loading". If the Promise object reports an error (rejected state), the component displays an error message; if the Promise object successfully captures data (in the fulfilled state), the component displays the obtained data.
Var RepoList = React. createClass ({
GetInitialState: function (){
Return {loading: true, error: null, data: null };
},
ComponentDidMount (){
This. props. promise. then (
Value => this. setState ({loading: false, data: value }),
Error => this. setState ({loading: false, error: error }));
},
Render: function (){
If (this. state. loading ){
Return <span> Loading... </span>;
}
Else if (this. state. error! = Null ){
Return <span> Error: {this. state. error. message} </span>;
}
Else {
Var repos = this. state. data. items;
Var repoList = repos. map (function (repo ){
Return (
<Li>
<A href={repo.html _ url }>{ repo. name} </a> ({repo. stargazers_count} stars) <br/> {repo. description}
</Li>
);
});
Return (
<Main>
<H1> Most Popular JavaScript Projects in Github <Ol> {repoList} </ol>
</Main>
);
}
}
});