React:一个javascript库,DOM的一个抽象层 JSX:React的语法糖 react bootstrap:react版的bootstrap formik:Form辅助库,Helper redux:组件间状态变化时的处理中心 route:处理路由
初步了解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 https://zh-hans.reactjs.org/docs/create-a-new-react-app.html#create-react-app npx create-react-app learn_react_bootstrap cd learn_react_bootstrap npm start 入门文档:https://zh-hans.reactjs.org/docs/hello-world.html https://zh-hans.reactjs.org/tutorial/tutorial.html react bootstrap库: https://react-bootstrap.github.io/getting-started/introduction/ npm install react-bootstrap bootstrap formik:https://formik.org/docs/tutorial redux:https://www.reduxjs.cn/introduction/getting-started react-router:https://reactrouter.com/web/guides/quick-start
React中一些基础概念 元素渲染 React库会维护一个JS的虚拟DOM对象,并由React DOM模块负责让网页的DOM和虚拟DOM保持一致。 使用ReactDOM.render()方法可以将元素渲染到DOM树。
例子:
1 2 3 4 5 6 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; const element = <h1>Hello</h1>; ReactDOM.render(element, document.getElementById('root'));
组件 把代码封装为方法,可在多处复用,可传参。 例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } class User extends React.Component { render() { return <Welcome name="Zjs" /> } } ReactDOM.render(<User />, document.getElementById('root'));
动态更新组件内的参数值 组件生命周期有三种状态,1. mounting(安装) 2.updating(更新) 3. unmounting (卸载) 每种状态分别有类似构造和析构的函数,will和did,进入状态前调用will,进入状态后调用did。
默认的组件就是render之后就完事了,想要动态更新就不行,如果想要动态更新(比如ajax)就要借助 this.state,组件内使用this.state的值,而this.state的值变化后,组件所使用的this.state值也会变,DOM就会重新渲染变化的值。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import { Button, Container, Row, Col } from 'react-bootstrap'; class TimeExample extends React.Component { // 组件构造函数,组件创建时被调用 constructor(props) { super(props); // 继承父类this对象,因为要使用this.state this.state = { date: new Date() }; console.log('init TimeExample'); } // 组件挂载之后调用 componentDidMount() { // setInterval 函数的作用是周期性调用一个函数,相当于一个定时器 // 将定时器的ID保存在this的变量中 // 可以理解为这里执行一个ajax,将返回值更新到this.state内,那么组件就可以从this.state内读取动态更新的值并更新DOM this.LoopID = setInterval( () => { this.setState({ date: new Date() }); console.log(this.state); }, 1000 ); } // 组件被卸载的时候调用,比如被close,被remove componentWillUnmount() { // 清除定时器 clearInterval(this.LoopID); } render() { return ( <div> <h2>Now: {this.state.date.toLocaleTimeString()}</h2> </div> ); } } ReactDOM.render(<TimeExample />, document.getElementById('root'));
事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import { Button, Modal, closeButton, Col } from 'react-bootstrap'; class ClickExample extends React.Component { // 构造方法,在state存储值 constructor(props) { super(props); this.state = { modal_show: false } } // 点击后改变state内的值,联动改变DOM clickMe() { this.setState({ modal_show: true }) // alert(); } // 隐藏 handleClose() { this.setState({ modal_show: false }) } // 使用react bootstrap的Button、Modal render() { return ( <> <Button variant="success" onClick={() => this.clickMe()}>绑定事件</Button> <Modal show={this.state.modal_show} onHide={() => { this.handleClose(); }} > <Modal.Header closeButton> <Modal.Title>Modal heading</Modal.Title> </Modal.Header> <Modal.Body>react bootstrap modal</Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={() => { this.handleClose(); }} > Close </Button> </Modal.Footer> </Modal> </ > ) } } ReactDOM.render(<ClickExample />, document.getElementById('root'));
if判断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import { Button, Modal, closeButton, Col } from 'react-bootstrap'; class ClickExample extends React.Component { // 构造方法,在state存储值 constructor(props) { super(props); this.state = { login_status: false // true-已登录 false-未登录 } } login() { this.setState({ login_status: true }) } logout() { this.setState({ login_status: false }) } render() { const login_status = this.state.login_status; // let buttons; // if (login_status) { // buttons = <Button variant="success" onClick={() => { // this.logout(); // }}>退出登录</Button> // } else { // buttons = <Button variant="success" onClick={() => { // this.login(); // }}>登录</Button> // } return ( <> {this.state.login_status ? <Button variant="success" onClick={() => { this.logout(); }}>退出登录</Button> : <Button variant="success" onClick={() => { this.login(); }}>登录</Button> } </ > ) } } ReactDOM.render(<ClickExample />, document.getElementById('root'));
数据渲染 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import { Table } from 'react-bootstrap'; import './index.css'; /* .table { width: 50%; margin: 0 auto; margin-top: 5%; } */ class Menu extends React.Component { constructor(props) { super(props); this.state = { data: [] }; } componentDidMount() { // ajax init data this.setState({ data: [ { 'id': 1, 'firstname': 'jun', 'lastname': 'zhang', }, { 'id': 5, 'firstname': 'jun2', 'lastname': 'zhang2', }, { 'id': 3, 'firstname': 'jun3', 'lastname': 'zhang3', }, ] }); } render() { const listItems = this.state.data.map((data) => <tr> <td>{data.id}</td> <td>{data.firstname}</td> <td>{data.lastname}</td> <td>{data.firstname}.{data.lastname}</td> </tr> ); return ( <> <Table striped bordered hover className="table"> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> {listItems} </tbody> </Table> </ > ) } } ReactDOM.render(<Menu />, document.getElementById('root'));
表单处理 使用formik这个form处理库 npm install formikhttps://formik.org/docs/tutorial#installation
使用yup做字段规则 校验 npm install yuphttps://github.com/jquense/yup
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import { InputGroup, Col, Button, Form } from 'react-bootstrap'; import './index.css'; import { Formik } from "formik"; import * as yup from "yup"; const schema = yup.object().shape({ username: yup.string().required('请填写用户名'), terms: yup.bool().required().oneOf([true], '请先阅读并同意协议'), }); function FormExample() { function submitForm(values) { console.log('ajax 提交数据'); console.log(values); } return ( <Formik validationSchema={schema} onSubmit={(values) => { submitForm(values) }} initialValues={{ username: '', terms: false, }} > {({ handleSubmit, handleChange, handleBlur, values, touched, isValid, errors, }) => ( <Form noValidate onSubmit={handleSubmit}> <Form.Row> <Form.Group as={Col} md="6" controlId="validationFormik03"> <Form.Label>用户名</Form.Label> <Form.Control type="text" placeholder="username" name="username" value={values.username} onChange={handleChange} isInvalid={!!errors.username} /> <Form.Control.Feedback type="invalid"> {errors.username} </Form.Control.Feedback> </Form.Group> </Form.Row> <Form.Group> <Form.Check required name="terms" label="我已认真阅读并同意协议" onChange={handleChange} isInvalid={!!errors.terms} feedback={errors.terms} id="validationFormik0" /> </Form.Group> <Button type="submit">提交</Button> </Form> )} </Formik> ); } ReactDOM.render(<FormExample />, document.getElementById('root'));
组件间共享父类的 state 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import { InputGroup, Col, Button, Form } from 'react-bootstrap'; import './index.css'; class CheckRate extends React.Component { render() { return ( <> {this.props.number > 6.5 ? <span>汇率高</span> : <span>汇率低</span>} </> ); }; } class Rate extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { input_rate: '' }; } handleChange(e) { this.setState({ input_rate: e.target.value }); } render() { const input_rate = this.state.input_rate; return ( <> <h2>汇率检测器,输入一个浮点值以检测汇率高低.</h2> <span>输入汇率:</span> <input value={input_rate} onChange={this.handleChange} /> <CheckRate number={input_rate} /> </> ); } } ReactDOM.render(<Rate />, document.getElementById('root'));
ajax 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import './index.css'; class Rate extends React.Component { // 组件挂载后 componentDidMount() { fetch("http://api.apishop.net/common/hearthStone/queryCardListByKeyword") .then(res => res.json()) .then( (result) => { console.log(result); }, (error) => { console.log("error"); console.log(error); } ) } render() { return ( <> </> ); } } ReactDOM.render(<Rate />, document.getElementById('root'));
redux 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 npm install redux import React from 'react'; import ReactDOM from 'react-dom'; import { createStore } from 'redux'; // 计数器 function counter(state = 0, action) { switch (action.type) { case 'ADD': return state + 1; break; case 'DEL': return state - 1; break; default: return state; break; } } // 创建一个状态对象 let store = createStore(counter); // 注册监听器,在状态改变时做对应处理 store.subscribe( () => { console.log(store.getState()) } ); // 更新state store.dispatch({ type: 'ADD' }); store.dispatch({ type: 'ADD' }); store.dispatch({ type: 'DEL' });
https://tech.meituan.com/2017/07/14/redux-design-code.html
route 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 npm install react-router-dom import React from 'react'; import reactDom from 'react-dom'; import { BrowserRouter as Router, Switch, Route, Link, BrowserRouter } from "react-router-dom"; function Home() { return ( <h2>首页</h2> ); } function About() { return ( <h2>关于我们</h2> ); } function Links() { return ( <h2>友情链接</h2> ); } export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/links">Links</Link> </li> </ul> </nav> <Switch> <Router exact path="/"> <Home /> </Router> <Router path="/about"> <About /> </Router> <Router path="/links"> <Links /> </Router> </Switch> </div> </Router> ); } reactDom.render(<App />, document.getElementById('root'));