# 3. State/props/refs ###### tags: `React` * 組件名稱必須為大寫開頭 * react 解析組件標籤後找到Demo > function Component ->調用Weather()將回傳的虛擬Dom轉為真實Dom 原 : 無法有state hook : `const [statename,setstate]=useState()` (State hook 也是一種解構賦值的寫法) ``` function Weather(){ const [count, setCount] = useState(0); //State hook return <h1>test</h1>;//必須有傳回值 } ``` > Class Component ->組件使用類定義 : new出來該類的實例,並且調用原型物件上的render方法 ``` class Weather extends React.Component{ /* constructor(props){ super(props) this.state = {count:0} this.changeWeather = this.changeWeather.bind(this) } */ state = {count:0} render(){ return } changeWeather = ()=>{ } } ``` * render()中的this 為該組件的物件實例(Weather) ` Weather.render()` * 組件自定義方法中this為undefined a) 強制綁定this: 通過函數對象的bind() b) 箭頭函數 --- > State 不能直接修改或更新,需呼叫`setState()` --- > props 通過標籤屬性從組件外向組件內傳遞data * 組件內部不可修改props數據 * 取值 ``` name = this.props.name password= this.props.password ``` `{name,password}=this.props` (解構賦值) `<a {...this.props}>{this.props.children}<a/>` 一口氣將所有的props放入<a>的屬性。 透過.children取得上層標籤body的內容。 * 賦值 1. 最基本寫法 要注意如果傳入值有形別則要用{}的方式型別才會正確 `<Demo name="tom" age={10} / >` 2. 擴展屬性: 與es的展開運算符不同,雖然結果是展開物件,但這是babel與react特有的定義且只有在標籤中有效 ``` person={name:"",ps:"",gender:""} <Person {...person}/> ``` 3. tag body -> children屬性 `<a>標籤體<a/>` = `<a children="標籤體"/>` * 限制props 需[prop-types](https://www.npmjs.com/package/prop-types)(npm install --save prop-types) ``` Person.propTypes = { name: PropTypes.string.isRequired, age: PropTypes.number. } ``` * 默認屬性值: ``` Person.defaultProps = { age: 18, sex:'男' } ``` --- > refs 組件內的標籤可以定義ref屬性來標識自己 1. 字符串形式的ref (不推薦使用) ` <input ref="input1"/>` 2. callback形式的ref ` <input ref={(c)=>{this.input1 = c}}` 3. createRef創建ref容器· ``` myRef = React.createRef() <input ref={this.myRef}/> ```