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") );