這次試著建立一個 Counter.js 在 src 目錄,將 Counter 的組件獨立成一個檔案:
import React, { Component } from 'react';
class Counter extends Component {
state = {
count: 0
}
addCount = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.addCount}>+1</button>
</div>
);
}
}
export default Counter;
請注意:檔名字首依然是大寫。
如果是 VSCode 的使用者,推薦 Reactjs code snippets 套件,打 rc 按下 tab 即可產出一個組件 code。
如果嘗試著在 index.js 那段,呼叫 Counter 組件時,給予一個初始值 10,怎麼做?
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Counter from './Counter'
ReactDOM.render(<Counter initial={10} />,
document.getElementById('root'));
那 Counter 這邊接受 initial 可以透過 props
的方式,不過由於 Function
都在 Counter 這邊,所以可以 React 內建的 constructor
函式來建立,:
class Counter extends Component {
constructor(props){
super(props)
this.state = {
count: props.initial
}
}
addCount = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.addCount}>+1</button>
</div>
);
}
}
constructor
是 React 的生命週期函式(後面會提到),目前只要記得constructor
是該物件被呼叫建立時,可以在裡面做什麼事,而我們在這建立的時間點,將constructor
的參數props
,也就是與父組件溝通的橋樑進行拿值。super
就是指的是這個組件,通常constructor
(props
)都搭配super
(props
)來進行初始化作業,關於super
與constructor
可以參考這篇,講得非常清楚。
現在已經可以透過父組件給予的初始值,讓子組件使用,那如果今天父組件不給值,不就會造成所謂的錯誤嗎?可以透過子組件設定的預設值,也就是即使父組件不給值,還是能有一個值能給子組件使用:
class Counter extends Component {
static defaultProps = {
count: 10
}
constructor(props){
super(props)
this.state = {
count: props.initial
}
}
addCount = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.addCount}>+1</button>
</div>
);
}
}
static 被稱作靜態方法,也代表該方法並不會被繼承。
那如果父組件傳的值,誤傳字串?
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Counter from './Counter'
ReactDOM.render(<Counter initial={10} />,
document.getElementById('root'));
可以發現 Counter 組件在使用時,遵循 JavaScript 的規則, "10" + 1 = 101,可以在 constructor
進行轉換:
constructor(props){
super(props)
this.state = {
count: parseInt(props.initial)
}
}
總結
這篇主要提到了 父子組件之間的一些溝通方式,在父組件呼叫子組件,不只是可以把值、方法傳入給子組件使用,當狀態及方法都在子組件時,父組件依然可以透過屬性的方式將初始值給帶入給子組件使用。