第 3 節練習:認識基本語法(JSX,Component,Props,State,useState() Hook,Binding,Styles)。
1. JSX Restrictions
JSX 是 Javascript 的語法擴充,在寫 React 時透過這個語法來描述使用者介面的外觀。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<App/>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
//function App() {
class App extends Component{
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
</div>
);
//return React.createElement('div', {classname: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
呈現結果:
2. Create a Funcional Component
建立 Person 目錄和 Person.js 檔案
Person.js
import React from 'react';
const person =() => {
return <p>I'm a Person</p>
}
export default person;
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
class App extends Component{
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<Person />
</div>
);
//return React.createElement('div', {classname: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
呈現結果:
3. Outputting Dynamic Content
Person.js
import React from 'react';
const person =() => {
return <p>I'm a Person and I am {Math.floor(Math.random() * 30)} years old.</p>
}
export default person;
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
class App extends Component{
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<Person />
<Person />
<Person />
</div>
);
//return React.createElement('div', {classname: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
呈現結果:
4. Working with Props
Person.js
import React from 'react';
const person =(props) => {
return <p>I'm {props.name} and I am {props.age} years old.</p>
}
export default person;
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
class App extends Component{
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<Person name="Max" age="28"/>
<Person name="Manu" age="29">My Hobbies:Racing</Person>
<Person name="Stephanie" age="26"/>
</div>
);
//return React.createElement('div', {classname: 'App'}, React.createElement('h1', null, 'Does this work now?'));
}
}
export default App;
呈現結果:
5. Understanding & Using State
state 是讓元件控制自己的狀態,主要作用是用元件保存,控制以及修改自己可變的狀態。
props 是讓外部對元件自己進行配置,是 React 父元件與子元件間溝通的橋樑,是靜態(唯獨)的,且是不可改變的。
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;
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
class App extends Component{
state = {
persons: [
{ name:'Max', age: 28 },
{ name:'Manu', age: 29 },
{ name:'Stephanie', age: 26 }
]
}
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<button>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;
呈現結果:
6. Handing Events with Methods & Manipulating the State
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
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 = 'Maximilion';
this.setState({
persons: [
{ name:'Maximilion', age: 28 },
{ name:'Manu', age: 29 },
{ name:'Stephanie', age: 27 }
]
})
}
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</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;
呈現結果:點按鈕時
7. Using the useState() Hook for State Manipulation
conset [ state, setState ] = useState(initialState);
回傳一個 state 的值,以及更新 state 的 function。
在首次 rander 時,回傳的 state 的值會跟第一個參數(initialState
)一樣。
setState
function 是用來更新 state。它接收一個新的 state 並將 component 的重新 render 排進隊列。
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { useState } from 'react';
import Person from './Person/Person';
//function App() {
//class App extends Component{
const app = props => {
const [ personsState, setPersonsState ] = useState({
persons: [
{ name:'Max', age: 28 },
{ name:'Manu', age: 29 },
{ name:'Stephanie', age: 26 }
]
});
const [otherState, setOtherState] = useState('Some other value');
console.log(personsState, otherState);
const switchNameHandler = () => {
//console.log('Was clicked!');
//DON'T DO THIS: this.state.persons[0],name = 'Maximilion';
setPersonsState({
persons: [
{ name:'Maximilion', age: 28 },
{ name:'Manu', age: 29 },
{ name:'Stephanie', age: 27 }
]
});
};
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<button onClick={switchNameHandler}>Switch name</button>
<Person name={personsState.persons[0].name} age={personsState.persons[0].age}/>
<Person name={personsState.persons[1].name} age={personsState.persons[1].age}>My Hobbies:Racing</Person>
<Person name={personsState.persons[2].name} age={personsState.persons[2].age}/>
</div>
);
}
export default app;
呈現結果:點按鈕時
8. Passing Method References Between Components
Person.js
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>
</div>
)
}
export default person;
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
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 = 'Maximilion';
this.setState({
persons: [
{ name:newName, age: 28 },
{ name:'Manu', age: 29 },
{ name:'Stephanie', age: 27 }
]
})
}
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<button onClick={this.switchNameHandler.bind(this, 'Maximilion')}>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!')}>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;
呈現結果:點 Menu 時
or App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
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 = 'Maximilion';
this.setState({
persons: [
{ name:newName, age: 28 },
{ name:'Manu', age: 29 },
{ name:'Stephanie', age: 27 }
]
})
}
render() {
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<button onClick={() => this.switchNameHandler('Maximilion!!')}>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!')}>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;
呈現結果:點按鈕時
9. Adding Two Way Binding
Person.js
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;
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
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 = 'Maximilion';
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, Wendy</h1>
<p>This is really working!</p>
<button onClick={() => this.switchNameHandler('Maximilion!!')}>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;
呈現結果:於第二個輸入框輸入時
10. Adding Styling with Stylesheets
在 Person 目錄建立 Person.css 檔案
Person.css
.Person{
width: 60%;
margin: 16px auto;
border: 1px solid #eee;
box-shadow: 0 2px 3px #ccc;
padding: 16px;
text-align: center;
}
Person.js
import React from 'react';
import './Person.css';
const person = (props) => {
return (
<div className="Person">
<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;
呈現結果:
11. Working with Inline Styles
App.js
// import logo from './logo.svg';
import './App.css';
// import { render } from 'react-dom';
import { Component } from 'react';
import Person from './Person/Person';
//function App() {
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 = 'Maximilion';
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() {
const style = {
backgroindColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor: 'pointer'
};
return (
<div className="App">
<h1>Hi, I'm a React App, Wendy</h1>
<p>This is really working!</p>
<button style={style} onClick={() => this.switchNameHandler('Maximilion!!')}>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;
呈現結果: