React 面向組件化編程javascript
面向對象 ----> 面向模塊 ----> 面向組件css
套路:html
注意: java
組件名必須大寫開頭;node
只能有一個根標籤;react
<input />虛擬DOM 元素必須有結束標籤面試
方式1. 工廠函數組件 (簡單組件) ----> 只能定義無狀態的組件npm
function MyComponent(){ // 只能 大寫開頭,區別於普通函數 return <h2>工廠函數組件(簡單組件)</h2> }
// 渲染函數組件標籤
// 內部直接調用 工廠組件函數 獲得虛擬組件函數 ReactDOM.render(<MyComponent/>, document.getElementById("outer"))
方式2: ES6 類組件 (複雜組件)編程
class MyComponent2 extends React.Component { // 1. 必須繼承 // 2. 必須大寫開頭 // 3. 必須重寫 render 方法, 指定 return 返回值 render (){ return <h2>ES6類組件(複雜組件)</h2> } }
// 渲染類組件標籤
// 內部會自動建立類的實例,並調用其 render() 方法獲得須要渲染的虛擬 DOM ReactDOM.render(<MyComponent/>, document.getElementById("outer"));
// 獲取到虛擬 DOM 對象 頁面上的 原生 DOM
組件的三大屬性:數組
面試題: 區別一下組件的 props 和 state 屬性
相同點: 都是組件實例的對象,用於保存數據
不一樣點:
state 保存組件自身內部可變化的數據
props 保存從外部傳入組件內部的數據,組件內部只讀而不修改
是組件對象最終要的 屬性,屬性值是一個對象 (能夠包含多個)
組件被稱爲 "狀態機"
更新狀態 從而 更新界面 ----> this.setState({stateName1 : newValue})
this.state 是組件私有的,經過調用 this.setState() 來改變它
this.setState() 每次修改之後,自動調用 this.render 方法,再次渲染組件
能夠經過 getInitialState() 方法初始化,在組件的生命週期中僅執行一次
var FavoriteButton=React.createClass({ getInitialState:function(){ return {favorite:false}; }, handleClick:function(event){ this.setState({favorite:!this.state.favorite}); }, render:function(){ var text=this.state.favorite? 'favorite':'un favorite'; return ( <div type='button' onClick={this.handleClick}> You {text} this. Click to toggle. </div> ); } }); --------------------- 做者:CrazyCodeBoy 來源:CSDN 原文:https://blog.csdn.net/fengyuzhengfan/article/details/52185921 版權聲明:本文爲博主原創文章,轉載請附上博文連接!
當 state 更新以後,組件就會從新渲染本身。
render() 方法依賴於 this.props 和 this.state ,
框架會確保渲染出來的 UI 界面老是與輸入( this.props 和 this.state )保持一致
實例: iLikeQuQ
class Like extends React.Component { // 組件類 constructor(props){ super(props) this.state = {isLikeMe: false} }
// 組件中自定義的方法的 this 默認指向 undefined
// 利用 箭頭函數 沒有本身的 this 來 在函數內使用 this
// 若要 更新組件的顯示,必須使用 組件的 setState() chgText = ()=>{ // this.state.isLikeMe = !this.state.isLikeMe 無效操做 this.setState({ isLikeMe: !this.state.isLikeMe }) } render(){ const isLikeMe = this.state.isLikeMe const text = isLikeMe?"I Like U.":"U Like Me." return <h2 onClick={this.chgText}>{text}</h2> } }
ReactDOM.render(<Like/>, document.getElementById("outer"));
每次點擊,改變了 狀態,那麼就會自動從新調用 render() 方法
props 對象
每一個組件只會根據 props 渲染了本身一次,props 是不可變的
<script src="https://cdn.bootcss.com/prop-types/15.6.2/prop-types.js"></script>
class Person extends React.Component { /**** 默認會執行 constructor (props){ super(props); // props 包含了組件標籤的全部屬性數據 } ****/ render(){ const {name, age, sex} = this.props; return ({ <ul> <li>姓名: {name}</li> <li>年齡: {age}</li> <li>性別: {sex}</li> </ul> }) } } // this.props.xxx // 1. 讀取屬性名 xxx 對應的 屬性值 Person.propTypes = { // 2. 設置 props 中屬性的約束條件 name: PropTypes.string.isRequired // 必須傳參,且 string } Person.defaultProps = { // 3. 設置 props 中屬性的默認值 age: 18, sex: "未知" } /**************************************/ const sun = { name: "孫悟空", age: 550, sex: "男" } // name 被 isRequired 修飾,必須傳,且類型必須爲 string ReactDOM.render(<Person name={sun.name} age={sun.age} sex={sun.sex}/>, document.getElementById("outer")); // ReactDOM.render(<Person {...sun}/>, document.getElementById("outer")); // 簡化寫法
優化爲: (propTypes, defaultProps , state 不須要給實例對象直接調用)
class Person extends React.Component { // 1. 給組件對象 設置 state 屬性 state = { isLikeMe: false } // 給類添加 屬性,只能 類 內部調用 // 2. 設置 props 中屬性的約束條件 static propTypes = { name: PropTypes.string.isRequired // 必須傳參,且 string } // 3. 設置 props 中屬性的默認值 static defaultProps = { age: 18, sex: "未知" } render(){ const {name, age, sex} = this.props; return ({ <ul> <li>姓名: {name}</li> <li>年齡: {age}</li> <li>性別: {sex}</li> </ul> }) } } /**************************************/ const sun = { name: "孫悟空", age: 550, sex: "男" } // name 被 isRequired 修飾,必須傳,且類型必須爲 string ReactDOM.render(<Person {...sun}/>, document.getElementById("outer")); // 簡化寫法
refs 對象
// 組件對象 refs 保存的是 ref 關聯的虛擬 DOM 元素 // refs {屬性: 屬性值} // refs {ref 的值: 對應的 DOM 元素對象} // refs {"left": <input>元素對象} class MyComponent extends ReactComponent { hint = ()=>{ console.log(this.refs.left.value); } handleBlur = (event)=>{ // console.log(this.refs.right.value); console.log(event.target.value); } render(){ return ({ <div> <input type="text" ref="left"/> <button onClick={this.hint}></button> <input type="text" ref="right" onBlur={this.handleBlur} /> </div> }) } } ReactDOM.render(<MyComponent/>, document.getElementById("oouter"))
ReactDOM.render(<Person name={sun.name} age={sun.age} sex={sun.sex}/>, document.getElementById("outer"));
傳一個 虛擬 DOM 標籤,組件.props.children
傳多個 虛擬 DOM 標籤,組件.props.children[{...},{...}...]
程序: 是對現實世界的模擬
class 必須用 className 代替
style 的屬性值必須 {{"color":"red", "font-size": "16px"}}
1. 箭頭函數的方式
2. 初始化執行 constructor() 時,bind 綁定 this 從而產生一個新的函數,指向組件對象
You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
解決:
使用 defaultValue 代替 value
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React</title> <link rel="stylesheet" type="text/css" href="./css/index.css" /> </head> <body> <div id="outer"></div> <!-- javascript 代碼 --> <script src="https://cdn.bootcss.com/react/16.7.0/umd/react.development.js"></script> <script src="https://cdn.bootcss.com/react-dom/16.7.0/umd/react-dom.development.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.js"></script> <script type="text/babel"> class ButtonText extends React.Component { // 組件類 hint = ()=>{ alert("left : "+this.refs.left.value) } centerInfo = (event)=>{ this.refs.tips.innerHTML = event.target.value } handleBlur = (event)=>{ console.log("right : "+event.target.value) } render(){ return ( <div> <div> <label> <input type="text" ref="left" defaultValue="Come on!"/> </label> <label> <input type="text" ref="center" onKeyUp={this.centerInfo}/> </label> <label> <input type="text" ref="right" onBlur={this.handleBlur}/> </label> </div> <button onClick={this.hint}>Tips</button> <p ref="tips">Hello there.</p> </div> ) } } ReactDOM.render(<ButtonText/>, document.getElementById("outer")); </script> </body> </html>
問題: 在 create-react-app 以後的項目,進行 npm run build 時,發現是 用了 "/" 絕對路徑,以至於找不到路徑
解決: 找到 node_modules/react-scripts/config/paths.js 第 45 行修改 "/" 爲 "./"
我的 './' 與 '/' 愚見,以爲 './' 更好,爲何官方設計是 /這樣的絕對路徑呢?