React
src/pages/Detail.js
1 import React from ‘react’; 2 3 clas Detail extends React.Compent { 4 render() { 5 return <p>This is React rendering HTML!</p> 6 } 7 } 8 9 export default Detail;
• import React from ‘react’ loads the React library, which is pretty central to our whole application and thus is required.
• classDetailextendsReact.Component{defines a new React component. React components can be big (like pages) or small (like a custom component to render breadcrumbs) and they are very flexible.
• render() { starts the render() method of our component. This is called by React when the component needs to be drawn to the screen, and need store turn something that can be drawn in the browser.
• export default Detail; The “export” keyword means this component is being exposed to the rest of our app to use, and “default” means it’s the only thing this class will expose.
Importing React Components using ES6
src/index.js
1 import React from 'react'; 2 import ReactDOM from 'react-dom'; 3 4 import Detail from './pages/Detal'; 5 6 ReactDOM.render( 7 <Detail />, 8 document.getElementById('app') 9 );
• import React from ‘react’ is a line you’ve seen before, and you’ll see again in this tutorial: it just sucks in the main React library so we can start work.
• import ReactDOM from ‘react-dom’ is new, and imports the React tools required to render to the DOM – that’s the name used for the document structure used to describe web pages and other similar documents.
• import Detail from ‘./pages/Detail’ is where we import our new React component into our app so that we can start using it.
• ReactDOM.render() is what kicks off (开始)the rendering of our entire(整个) app, and it takes two parameters(参数): some JSX to render and where to render it to.
• <Detail /> is the first parameter we ask React to render, and it’s the JSX name of our Detail component.
• document.getElementById(‘app’) is the second parameter to the render method, and it tells React we want it to render inside the HTML element named “app” – that’s inside the index.html file we made earlier.
Now, before we continue you probably have some questions. Let me try to answer some:
• Why does Detail.js have a capital letter? This isn’t needed, but it’s stylistically(文档上) preferred.
• How does JSX know what <Detail /> means?We don’t give the component a name inside Detail.js, so instead the name comes from the way we import it: if you use import Bob from './pages/Detail'; then you could write <Bob /> and it would work just fine. (But please don’t do that if you value your sanity!)
• Can I put lots of components in Detail.js? You can if you want to, but again it’s preferable not to if you value your sanity. Stick to one component per file if you can.
• Do I have to render stuff inside my component? No, but React does need something to render at this point.Whenyou’re a more experienced React developer you’ll learn more about this
To recap, so far you’ve learned:
1. How to install Webpack, Babel and React for development with ES6.
2. How to create a basic React component and import it into an application.
3. How to write simple JSX to render content.
What are React Props?
src/index.js
1 import React from 'react'; 2 import ReactDOM from 'react-dom'; 3 4 import Detail from './pages/Detail'; 5 6 ReactDOM.render( 7 <Detail message="This is coming from propos!" /> 8 document.getElementById('app') 9 );
src/pages/Detail.js
1 import React from 'react'; 2 3 class Detail extends React.Compent { 4 render() { 5 return <p>{this.props.message}</p>; 6 } 7 } 8 9 export default Detail;
How to Write if/else Conditional Statements in JSX
In React is not use if/else ,but use double or even triple ternary expressions (三元运算符);
src/pages/Detail.js
1 render() { 2 return <p> 3 { 4 chance.first() == 'John' 5 ? ‘Hello, wei!’ 6 : 'Hello, yuan!' 7 } 8 </p> 9
Using JSX to Render Several Elements at Once
1 render() { 2 return <p>Hello, {chance.first()}. </p> 3 <p>You're from {chance.country({ full: true})}.</p> 4 }//is wrong.因为render中只能返回一个顶级标签。如果想返回多个元素可以使用<div>标签
1 render() { 2 return (<div> 3 <p>Hello, {chance.first()}. </p> 4 <p>You're from {chance.country({ full: true})}.</p> 5 </div>); 6 }//is right
Handling Events with JSX: onClick
src/pages/Detail.js
1 class Detail extends React.Compent { 2 buttonClicked() { 3 console.log('Buton was clicked!') 4 } 5 6 render() { 7 return (<div> 8 <p>Hello, {chance.first()}.</p> 9 <p>You're from {chance.country({ full: true })}.</p> 10 <button onClick = {this.buttonClicked}>Meet Someone new</button> 11 </div>); 12 } 13 } 14 15 export default Detail;
src/papges/Detail.js
1 <button onClick = {this.buttonClicked.bind(this)}>Meet Someone New</button> //用blind()来绑定this
Changing a React Component’s State with setState()
1 buttononClicked() { 2 const newState = { 3 name: chance.first() 4 }; 5 6 this.setState(newState); 7 }
React ES6 class constructor super()
When writting React using the ES6 class syntax like this:
1 class MyClass extends React.component {
2 constructor () {
3 super()
4 }
5 }
Two questions may arise:
- Is it necessary to call
super()
insideconstructor
? - What is the difference between callling
super()
andsuper(props)
?
Answer #1
Always call
super()
if you have a constructor and don't worry about it if you don't have a constructor(如果你有一个构造函数,你总会调用super())
Calling super()
is necessary only if you need to have a constructor
. Take a look at this code:(调用super()的前提是你必须有一个构造函数)
1 class MyClass extends React.compent { 2 render() { 3 return<div>Hello {this.props.world }</div>; 4 } 5 }
The code above is perfectly valid(有效的). You don't have to call super()
for every react component you create. However, if there is a constructor in your code, then you MUST call super:
class MyClass extends React.compent {
constructor() {
console.log(this) //Error: 'this' is not allowed before super()
}
}
The reason why this
cannot be allowed before super()
is because this
is uninitialized(未初始化的) if super() is not called [1]
You may think you can get away with an empty constructor without callling super()
:
1 class MyClass extends React.compent {
2 constructor() {} //Error: 'this' is not allowed before super() 3 45}
ES6 class constructors MUST call super
if they are subclasses. Thus, you have to call super()
as long as you have a constructor. (But a subclass does not have to have a constructor)
Answer #2
Call
super(props)
only if you want to accessthis.props
inside the constructor. React automatically set it for you if you want to access it anywhere else.
The effect of passing props
when calling super()
allows you to access this.props
in the constructor:
1 class MyClass extends React.component{ 2 constructor(props){ 3 super(props); 4 console.log(this.props); // prints out whatever is inside props 5 6 } 7 }
There is no need to pass props
into the constructor if you want to use it in other places. Because React automatically set it for you [2]
1 class MyClass extends React.component{ 2 render(){ 3 // There is no need to call `super(props)` or even having a constructor 4 5 // this.props is automatically set for you by React 6 7 // not just in render but another where else other than the constructor 8 9 console.log(this.props); // it works! 10 11 } 12 }
Rendering an Array of Data with map() and JSX
1 <div> 2 <p key="1">Hello, Jim from Australia!</p> 3 <p key="2">Hello, Dave from Malaysia!</p> 4 <p key="3">Hello, Charlotte from Thailand!</p> 5 </div> 6 7 8 render() { 9 return ( <div> 10 {this.state.people.map((person, index) => ( 11 ))} 12 </div>); 13 } //tips:使用map遍历时,需要给子元素添加一个key,作为唯一的标识,而且key值必须要连续
Fetching Ajax Data from GitHub using SuperAgent
src/pages/Detail.js
1 import ajax from 'superagent'; 2 3 4 compentWillMount() { 5 ajax.get('https://api.github.com/repos/facebook/react/commits') 6 .end((error, response) => { 7 if(!error && response) { 8 this.setState({ commits: response.body }); 9 } else { 10 console.log('There was an error fetching from GitHub', error); 11 } 12 } 13 ); 14 }
1. componentWillMount() is the name of the method, and needs to be named exactly this in order for React to call it.
2. ajax.get(‘https://api.github.com/repos/facebook/react/commits’)tells SuperAgent to fetch the list of commits to the React project from GitHub. I chose GitHub because they have a simple API that doesn’t require authentication.
3. .end((error, response)⇒{ tells SuperAgent what to do when the request finishes: it should run the anonymous function that follows.
4. if(!error&&response){start saconditional statement:th efollowing should run only if there was no error and there was a response from the server.
5. this.setState({ commits: response.body }) updates our component’s state using the body value of the SuperAgent response.
6. } else { the other half of our conditional statement: if there was an error or if the server provided no response. 7. console.log(…) print an error message to the browser console window.
7. console.log(…) print an error message to the browser console window.
Introducing React Router
All the work we’ve done so far has either been inindex.js or Detail.js, but now we’re going to add a third file called List.js that will render a home page for our app. From there, users will be able to select a GitHub repository, and doing so will show Detail.js as before.
So, we’ll go from having just one page listing all the React commits, forks and pulls on GitHub, to having a homepage first where users can select React, React Native, Jest, or other Facebook projects of our choosing. This involves a fairly big change, so we’re going to do this in two parts: first implement React Router in a way that preserves the exact behavior we have right now, then second add the new home page.
If you were wondering, React Router is a component that loads different pages depending on the URL your user asked for. So if the user goes tohttp://localhost:8080/helloit would serve one page, and http://localhost:8080/world would serve a different page.
Well, that’s not strictly true. To avoid having to add a server configuration, the pages React Router serves up will all start with/#/, e.g. http://localhost:8080/#/hello. This means thatindex.htmlwill automaticallybeusedtorenderallpages,whichinturnmeansthatReactRouterwillbeabletoload the right page.
src/index.js
1 import React from 'react'; 2 import ReactDOM from 'react-dom'; 3 import { Router, Route, IndexRoute } from 'react-router'; 4 import createHistory from 'histroy/lib/createHistory'; 5 6 import Detail from '.page/Detail'; 7 8 ReactDOM.render( 9 <Router> //<Router history={creatHistory({ queryKey: false})} 10 <Route path="/" compent={ Detail } /> // onUpdate={() => window.sorollTo(0,0)}>//is right 11 </Router>, 12 document.getElementById('app') 13 );//is wrong
//剖析Router,Route The first import brings three components, of which we’ll be using two immediately and the other shortly. Router is React Router itself, which takes a listofURLs and React components and puts the two together. Route is one individual URL mapping, e.g. the URL detail and our Detail component. IndexRoute is used as a default route; we’ll get onto that soon.