1.安裝腳手架
npm install -g create-react-app (全局安裝時應在cmd下執行命令)
2.創建項目
create-react-app myapp
3.啟動
npm start
4.元素渲染
let h1 = <h1>hellow</h1> 使用jsx語法創建js元素對象(注意:jsx元素對象或者組件對象只有一個根節點)
函數式組件渲染
function Clock(props){ return ( <div> <h1>現在的時間是:{props.date.toLocaleTimeString()}</h1> </div> ) } ReactDOM.render( <Clock date={new date()} /> , document.getElementById('root') );
類組件渲染
class Input extends React.Component { constructor(props) { super(props); } render() { let { props } = this; return ( <p>接收父組件傳值:{props.userName}</p> ); } }
5.組件通信
class Child extends React.Component { constructor(props) { super(props); } render() { let { props } = this; return ( <h1 onClick={() => { props.getChildProps("這是從子組件傳的值"); // 通過調用父組件的方法向父組件傳值 }} > {props.val} </h1> ); // 接收父組件傳值 } } class Parend extends React.Component { constructor(props) { super(props); } getChildProps(props) { console.log("接收子組件傳值"); // 接收子組件傳值 } render() { let val = "這是從父組件傳的值"; return <Child val={val} getChildProps={this.getChildProps}></Child>; // 通過屬性綁定向子組件傳值或者方法 } }
6.事件處理
class Child extends React.Component { constructor(props) { super(props); this.onClick.bind(this); } onClick(param) { console.log(param + "觸發事件"); } render() { return ( <div> <button onClick={() => { this.getChildProps("傳參"); // 通過箭頭函數調用方法傳值 }} > click </button> <button data-params="傳參" onClick={ this.click // 通過data-xx=yy傳值 微信小程序就是模仿的react } > click </button> </div> ); } }
7.列表渲染
render() { let { props } = this; return ( <header> <ul> {props.nav.map((item) => { return ( <li key={item} onClick={() => { this.onnav(item); }} > {item} </li> ); })} </ul> </header> ); }
8.插槽
// parent render() { return ( <Child> <p data-index="1">a</p> <p data-index="2">b</p> <p data-index="3">c</p> </Child> ); } // child props.children就是插值 遍歷每個插值的props並獲取每個插值上傳的值 render() { let { props } = this; return ( // <Child> // <p data-index="1">a</p> // <p data-index="2">b</p> // <p data-index="3">c</p> // </Child> <ul> {props.children.map((item) => { <li> {item.props["data-index"]}-{item} </li>; })} </ul> ); }
9.路由
安裝引入
// hash模式 // import { HashRouter as Router, Link, Route } from "react-router-dom"; // history模式 import { BrowserRouter as Router, Link, Route, Redirect, // 重定向 Switch, // 被組件包裹的route只匹配一個,如果有相同的地址 則只匹配第一個 } from "react-router-dom";
使用
Link組件 相當於vue的router-link let query = { pathname: "/news", // 路徑 search: "?username=admin", // get請求 hash: "xxx", // 設置hash值 // 傳入組價的值 state: { msg: "hellow", }, }; <Link to={query}>News</Link> // 路由傳參 <Link to="/books">Books</Link> <Link to="/movies/123456" replace> // 路由傳參 Route組件 <Route path="/news" exact component={News}></Route> // 動態路由匹配 <Route path="/movies/:id" exact component={Movies}></Route> Redirect 重定向組件 <Redirect to="/movies"></Redirect>
示例
class News extends React.Component { constructor(props) { super(props); this.state = {}; } render() { let { props } = this; console.log(props); // 接收link to傳參 return ( <Router> <h1>新聞</h1> </Router> ); } } class Books extends React.Component { constructor(props) { super(props); this.state = {}; } toNews(props) { console.log(props); props.history.push("/news", { msg: "傳參" }); } render() { return ( <div> <h1>書籍</h1> <button onClick={() => { this.toNews(this.props); }} > 跳轉到新聞頁 by 方法 </button> </div> ); } } class Movies extends React.Component { constructor(props) { super(props); this.state = {}; } render() { let { props } = this; return <h1>電影 {props.match.params.id}</h1>; // 接收動態路由傳參 } } // 重定向 -- 用的比較少 function redir(props) { console.log(props); if (props.location.state.code === 500) { return <Redirect to="/books"></Redirect>; } else { return <Redirect to="/movies"></Redirect>; } } class App extends React.Component { constructor(props) { super(props); this.state = {}; } render() { let query = { pathname: "/news", // 路徑 search: "?username=admin", // get請求 hash: "xxx", // 設置hash值 // 傳入組價的值 state: { msg: "hellow", }, }; let params = { pathname: "/redir", state: { msg: "重定向", code: 500, }, }; return ( <Router> <div className="nav"> {/* 路由傳參 */} <Link to={query}>News</Link> <Link to="/books">Books</Link> {/* 動態路由傳參 */} <Link to="/movies/123456" replace> Movies </Link> <Link to={params}>點擊跳轉到電影頁</Link> </div> <Switch> <Route path="/news" exact component={News}></Route> <Route path="/news" exact component={() => <h1>新聞</h1>}></Route> <Route path="/books" exact component={Books}></Route> <Route path="/movies/:id" exact component={Movies}></Route> <Route path="/redir" exact component={redir}></Route> </Switch> </Router> ); } }
10.redux
安裝
cnpm install redux react-redux --save
案例,實現一個計數器
import React from "react"; import { connect } from "react-redux"; // Store 收到 Action 以后,必須給出一個新的 State,這樣 View 才會發生變化。這種 State 的計算過程就叫做 Reducer。 // Reducer 是一個函數,它接受 Action 和當前 State 作為參數,返回一個新的 State。 // 函數名是count -> 就是返回的state.count export const count = (state = 0, action) => { switch (action.type) { case "ADD_COUNT": return state + 1; case "SUB_COUNT": return state - 1; default: return state; } }; // 組件 const Count = ({ count, handle }) => { return ( <div> <button onClick={() => handle(1)}>+</button> <span>{count}</span> <button onClick={() => handle(2)}>-</button> </div> ); }; const handle = (type) => ({ type: type === 1 ? "ADD_COUNT" : "SUB_COUNT", // type為畢傳值 elsePrama: [], // 其他參數 }); // 獲取store const mapStateToProps = (state) => ({ count: state.count, }); // 設置store const mapDispatchToProps = (dispatch) => ({ handle: (type) => dispatch(handle(type)), }); // 連接React組件與 Redux store export default connect(mapStateToProps, mapDispatchToProps)(Count);
// 在入口文件index.js里面 import React from "react"; import ReactDOM from "react-dom"; import { createStore } from "redux"; import { Provider } from "react-redux"; const store = createStore(count); ReactDOM.render( <React.StrictMode> <Provider store={store}> <Count></Count> </Provider> </React.StrictMode>, document.getElementById("root") );