React 1-6
the official React documentation: https://reactjs.org/
Here's the finished source code: https://codepen.io/anon/pen/MELQaQ
2.14 Arrow Function:
const print = (name) =>{
console.log(name);
}
only one argument: 只有一个参数可以省略括号
const print = name =>{
console.log(name);
}
no arg:
const print = () =>{}
const multiply = number => number * 2
console.log(multiply(2));
3. Export Import


Classes, Properties and Method
class Person extends Human { constructor(){ super(); this.name='max'; } printMyName() { console.log(this.name); } }
等于
class Person extends Human{ name='max'; print = () => console.log(this.name); }
3.39 Props &State

3.43 manipulating state
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 26 }
],
otherState: 'some other value'
};
switchNameHandler = () => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState({
persons: [
{ name: 'Maximilian', age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 27 }
]
});
};
render() {
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p>This is really working!</p>
<button onClick={this.switchNameHandler}>Switch Name</button>
<Person
name={this.state.persons[0].name}
age={this.state.persons[0].age}
/>
<Person
name={this.state.persons[1].name}
age={this.state.persons[1].age}
>
My Hobbies: Racing
</Person>
<Person
name={this.state.persons[2].name}
age={this.state.persons[2].age}
/>
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
person.js
import React from 'react'; const person = ( props ) => { return ( <div> <p>I'm {props.name} and I am {props.age} years old!</p> <p>{props.children}</p> </div> ) }; export default person;
class-based
因为用()=>这种语法 给一个property一个function 所以this可以用 否则不可以
{this.switchNameHandler}不加括号,加了是瞬间渲染的,不加是调用时作为reference
click={this.switchNameHandler.bind(this, 'Max!')} bind 后面是一个参数列表传进function
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 26 }
],
otherState: 'some other value'
}
switchNameHandler = (newName) => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState( {
persons: [
{ name: newName, age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 27 }
]
} )
}
nameChangedHandler = (event) => {
this.setState( {
persons: [
{ name: 'Max', age: 28 },
{ name: event.target.value, age: 29 },
{ name: 'Stephanie', age: 26 }
]
} )
}
render () {
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p>This is really working!</p>
<button onClick={() => this.switchNameHandler('Maximilian!!')}>Switch Name</button>
<Person
name={this.state.persons[0].name}
age={this.state.persons[0].age} />
<Person
name={this.state.persons[1].name}
age={this.state.persons[1].age}
click={this.switchNameHandler.bind(this, 'Max!')}
changed={this.nameChangedHandler} >My Hobbies: Racing</Person>
<Person
name={this.state.persons[2].name}
age={this.state.persons[2].age} />
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;

import React from 'react'; const person = ( props ) => { return ( <div> <p onClick={props.click}>I'm {props.name} and I am {props.age} years old!</p> <p>{props.children}</p> <input type="text" onChange={props.changed} value={props.name} /> </div> ) }; export default person;
two way binding
3.48 Adding Styling
需要import css into js file
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 26 }
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState( {
persons: [
{ name: newName, age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 27 }
]
} )
}
nameChangedHandler = (event) => {
this.setState( {
persons: [
{ name: 'Max', age: 28 },
{ name: event.target.value, age: 29 },
{ name: 'Stephanie', age: 26 }
]
} )
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons: !doesShow});
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p>This is really working!</p>
<button
style={style}
onClick={this.togglePersonsHandler}>Switch Name</button>
{
this.state.showPersons ?
<div >
<Person
name={this.state.persons[0].name}
age={this.state.persons[0].age} />
<Person
name={this.state.persons[1].name}
age={this.state.persons[1].age}
click={this.switchNameHandler.bind(this, 'Max!')}
changed={this.nameChangedHandler} >My Hobbies: Racing</Person>
<Person
name={this.state.persons[2].name}
age={this.state.persons[2].age} />
</div> :null
}
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
more elelgant way 判断
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 26 }
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState( {
persons: [
{ name: newName, age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 27 }
]
} )
}
nameChangedHandler = (event) => {
this.setState( {
persons: [
{ name: 'Max', age: 28 },
{ name: event.target.value, age: 29 },
{ name: 'Stephanie', age: 26 }
]
} )
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons: !doesShow});
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
let persons = null;
if(this.state.showPersons){
persons = (
<div>
<Person
name={this.state.persons[0].name}
age={this.state.persons[0].age} />
<Person
name={this.state.persons[1].name}
age={this.state.persons[1].age}
click={this.switchNameHandler.bind(this, 'Max!')}
changed={this.nameChangedHandler} >My Hobbies: Racing</Person>
<Person
name={this.state.persons[2].name}
age={this.state.persons[2].age} />
</div>
);
}
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p>This is really working!</p>
<button
style={style}
onClick={this.togglePersonsHandler}>Switch Name</button>
{ persons}
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
3.56 Outputting lists (turn into jsx object)
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 26 }
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState( {
persons: [
{ name: newName, age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 27 }
]
} )
}
nameChangedHandler = (event) => {
this.setState( {
persons: [
{ name: 'Max', age: 28 },
{ name: event.target.value, age: 29 },
{ name: 'Stephanie', age: 26 }
]
} )
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons: !doesShow});
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
let persons = null;
if(this.state.showPersons){
persons = (
<div>
{this.state.persons.map(person => {
return <Person
name={person.name}
age={person.age} />//jsx object
})}
</div>
);
}
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p>This is really working!</p>
<button
style={style}
onClick={this.togglePersonsHandler}>Switch Name</button>
{persons}
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
delete list
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 26 }
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState( {
persons: [
{ name: newName, age: 28 },
{ name: 'Manu', age: 29 },
{ name: 'Stephanie', age: 27 }
]
} )
}
nameChangedHandler = (event) => {
this.setState( {
persons: [
{ name: 'Max', age: 28 },
{ name: event.target.value, age: 29 },
{ name: 'Stephanie', age: 26 }
]
} )
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons: !doesShow});
}
deletePersonHandler = (personIndex) => {
const persons = this.state.persons;
persons.splice(personIndex, 1);//删除数组中的元素,在index的地方删除一个元素
this.setState({ persons: persons });
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
let persons = null;
if(this.state.showPersons){
persons = (
<div>
{this.state.persons.map((person,index) => {
return <Person
click={() => this.deletePersonHandler(index)}//function带参数 必须那么写
name={person.name}
age={person.age} />//jsx object
})}
</div>
);
}
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p>This is really working!</p>
<button
style={style}
onClick={this.togglePersonsHandler}>Switch Name</button>
{persons}
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
map(a,b) a是元素,b是索引
会报warning,改进:
deletePersonHandler = (personIndex) => { const persons = this.state.persons; persons.splice(personIndex, 1);//删除数组中的元素,在index的地方删除一个元素 this.setState({ persons: persons });
因为object 和array 是 reference type
persons有着上面persons的索引
然后下面修改的是索引。
好的步骤是先复制一个 然后再修改 而不是直接修改索引
const persons = this.state.persons.slice(); slice()复制array 然后赋给persons
3.60 Flexible List
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{id:'1', name: 'Max', age: 28 },
{id:'2', name: 'Manu', age: 29 },
{id:'3', name: 'Stephanie', age: 26 }
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState( {
persons: [
{name: newName, age: 28 },
{name: 'Manu', age: 29 },
{name: 'Stephanie', age: 27 }
]
} )
}
nameChangedHandler = (event, id) => {
const personIndex = this.state.persons.findIndex(p => {
return p.id === id;//这个看不懂
});
const person = { ...this.state.persons[personIndex] };
person.name = event.target.value;
const persons = [...this.state.persons];
persons[personIndex] = person;
this.setState({
persons: persons
});
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons: !doesShow});
}
deletePersonHandler = (personIndex) => {
const persons = this.state.persons.slice();
//const persons = [...this.state.persons];
persons.splice(personIndex, 1);
this.setState({ persons: persons });///bhb
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
let persons = null;
if(this.state.showPersons){
persons = (
<div>
{this.state.persons.map((person,index) => {
return <Person
click={() => this.deletePersonHandler(index)}
name={person.name}
age={person.age}
key={person.id}//key 是保留字吗
changed={(event)=>this.nameChangedHandler(event,person.id)}
/>//jsx object???
})}
</div>
);
}
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p>This is really working!</p>
<button
style={style}
onClick={this.togglePersonsHandler}>Switch Name</button>
{persons}
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
5.67 Styling Class Dynamic
//let classes = [ 'red','bold'].join(' '); let classes = []; if (this.state.persons.length <= 2) { classes.push('red');//push red 给这个array } if (this.state.persons.length <= 1) { classes.push('bold'); } return ( <div className="App"> <h1>Hi, I'm a React App</h1> <p className={classes.join(' ')}>This is really working!</p> <button style={style} onClick={this.togglePersonsHandler}>Switch Name</button> {persons} </div> );
5.70 Styled Components
import React from 'react'; /*import './Person.css';*/ /*import Radium from 'radium';*/ import styled from 'styled-components'; const StyledDiv = styled.div` width:60%; margin:16px; border:1px solid #eee; box-shadow: 0 2px 3px #ccc; padding: 16px; text-align: center; `;// 这已经是一个三方库形成的react component了 所以不需要用function括住它 const person = ( props ) => { return ( /*<div className="Person">*/ <StyledDiv> <p onClick={props.click}>I'm {props.name} and I am {props.age} years old!</p> <p>{props.children}</p> <input type="text" onChange={props.changed} value={props.name} /> </StyledDiv> ) }; export default person;
同时要改动代码成为css,因为不再用jsx进行渲染
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
import styled from 'styled-components';
const StyledButton = styled.button`
background-color: ${props => props.alt ? 'red' : 'green'};
color: white;
font: inherit;
border: 1px solid blue;
padding: 8px;
cursor: pointer;
&:hover {
background-color: ${props => props.alt?'blue':'salmon'};
color: black;
}
`;
class App extends Component {
state = {
persons: [
{id:'1', name: 'Max', age: 28 },
{id:'2', name: 'Manu', age: 29 },
{id:'3', name: 'Stephanie', age: 26 }
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
// console.log('Was clicked!');
// DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
this.setState( {
persons: [
{name: newName, age: 28 },
{name: 'Manu', age: 29 },
{name: 'Stephanie', age: 27 }
]
} )
}
nameChangedHandler = (event, id) => {
const personIndex = this.state.persons.findIndex(p => {
return p.id === id;//这个看不懂
});
const person = { ...this.state.persons[personIndex] };
person.name = event.target.value;
const persons = [...this.state.persons];
persons[personIndex] = person;
this.setState({
persons: persons
});
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons: !doesShow});
}
deletePersonHandler = (personIndex) => {
const persons = this.state.persons.slice();
//const persons = [...this.state.persons];
persons.splice(personIndex, 1);
this.setState({ persons: persons });///bhb
}
render() {
let persons = null;
if(this.state.showPersons){
persons = (
<div>
{this.state.persons.map((person,index) => {
return <Person
click={() => this.deletePersonHandler(index)}
name={person.name}
age={person.age}
key={person.id}//key 是保留字吗
changed={(event)=>this.nameChangedHandler(event,person.id)}
/>//jsx object???
})}
</div>
);
/*style.backgroundColor = 'red';*/
/* style[':hover']= {
backgroundColor: 'salmon',
color: 'black'
}*/
}
//let classes = [ 'red','bold'].join(' ');
let classes = [];
if (this.state.persons.length <= 2) {
classes.push('red');//push red 给这个array
}
if (this.state.persons.length <= 1) {
classes.push('bold');
}
return (
<div className="App">
<h1>Hi, I'm a React App</h1>
<p className={classes.join(' ')}>This is really working!</p>
<StyledButton alt={this.state.showPersons}
onClick={this.togglePersonsHandler}>Switch Name</StyledButton>
{persons}
</div>
);
// return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
6.81 Debugging
import React, { Component } from 'react';
class ErrorBoundary extends Component {
state = {
hasError: false,
errorMessage:''
}
componentDidCatch = (error, info) => {
this.setState({ hasError: true, errorMessage: error });
}
render() {
if (this.state.hasError) {
return <h1>{this.state.errorMessage}</h1>;
} else {
return this.props.children;//这是执行它的子类吗
}
}
}
export default ErrorBoundary;
{this.state.persons.map((person,index) => {
return <ErrorBoundary key={person.id}><Person
click={() => this.deletePersonHandler(index)}
name={person.name}
age={person.age}
//key 是保留字吗
changed={(event)=>this.nameChangedHandler(event,person.id)}
/></ErrorBoundary>//jsx object???
})}
浙公网安备 33010602011771号