//引入相关库 <script type="text/javascript" src="../js/react.development.js"></script> <script type="text/javascript" src="../js/react-dom.development.js"></script> <script type="text/javascript" src="../js/babel.min.js"></script> <script type="text/babel"> //必须声明babel // 建立虚拟DOM元素 const vDom = <h1>Hello React</h1> // 千万不要加引号 // 渲染虚拟DOM到页面真实DOM容器中 ReactDOM.render(vDom, document.getElementById('test')) </script>
特别
的通常js对象var element = React.createElement('h1', {id:'myTitle'},'hello')
<body> <div id="test"></div> </body> <script type="text/babel"> // 建立虚拟DOM对象 const vDom1 = React.createElement('p',{id: 'myId1', className: 'myClass1'}, '珂朵莉',vDom3); // 将虚拟DOM对象插入到页面的指定容器中,渲染虚拟DOM(元素) ReactDOM.render(vDom1, document.getElementById('test1')); //方法一 //方法二 const id = 'myId2'; const content = '我永远喜欢珂朵莉'; const vDom3 = React.createElement('span', {}, 'daisiki'); const vDom2 = <div><h2 id={id } className="myClass2">{content}</h2>{vDom3}</div> // 将虚拟DOM对象插入到页面的指定容器中 ReactDOM.render(vDom2, document.getElementById('test2')); const list = ['1', '2', '3', '4']; ReactDOM.render( <ul> { list.map(( item,index) => <li key={index}>{item}</li> ) } </ul> ,document.getElementById('test3')) <script>
1)全称: JavaScript XML 2)react定义的一种相似于XML的JS扩展语法: XML+JS 3)做用: 用来建立react虚拟DOM(元素)对象 a.var ele = <h1>Hello JSX!</h1> b.注意1: 它不是字符串, 也不是HTML/XML标签 c.注意2: 它最终产生的就是一个JS对象 4)标签名任意: HTML标签或其它标签 5)标签属性任意: HTML标签属性或其它 6)基本语法规则 a.遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签须要特别解析 b.遇到以 { 开头的代码,以JS语法解析: 标签中的js代码必须用{ }包含, //待定:* if/for循环 不能用 7)babel.js的做用 a.浏览器不能直接解析JSX代码, 须要babel转译为纯JS的代码才能运行 b.只要用了JSX,都要加上type="text/babel", 声明须要babel来处理
定义组件(2种方式)javascript
/*方式1: 工厂函数组件(简单组件)*/ function MyComponent () { return <h2>工厂函数组件(简单组件)</h2> } /*方式2: ES6类组件(复杂组件)*/ class MyComponent2 extends React.Component { render () { console.log(this) // MyComponent2的实例对象 return <h2>ES6类组件(复杂组件)</h2> } }
渲染组件标签html
ReactDOM.render(<MyComponent />, document.getElementById('example1'))
虚拟DOM元素必须有结束标签前端
初始化java
name: 'Mary'}node
constructor (props) { super(props) console.log(props) // 查看全部属性 }
组件内的标签均可以定义ref属性来标识本身, 用来获取DOM元素
在组件中能够经过this.msgInput来获得对应的真实DOM元素react
a. <input type="text" ref={this.createRef}/> (推荐使用) b. <input type="text" ref={input => this.funcRef = input}/> c. <input type="text" ref="stringRef" /> (即将废弃) d. 回调函数在组件初始化渲染完或卸载时自动调用
做用: 经过ref获取组件内容特定标签对象, 进行读取其相关数据webpack
1.<input type="text" ref={this.createRef}/> 2.<input type="text" ref={(input) => this.funcRef = input}/> 3.<input type="text" ref="stringRef"/> constructor(props) { super(props); this.createRef = React.createRef(); } // 获取input标签的值 1. this.createRef.current 2. console.log(this.funcRef); 3. console.log(this.refs.stringRef);
经过onXxx属性指定组件的事件处理函数(注意大小写)ios
经过event.target获得发生事件的DOM元素对象git
<input onFocus={this.handleClick}/> handleFocus(event) { event.target //返回input对象 }
2)在组件类中自定义的方法中this为undefined程序员
React组件中函数this指向规则
1.拆分组件:根据页面功能拆分 APP AddTodo TodoList 2.实现静态组件 先实现大的组件(最外层的),再实现里面的组件 先有一个基本的显示效果 3.实现动态组件 1.需不须要定义状态数据? 看页面是否有变化,有变化就要定义状态数据 2.状态数据定义在哪里? APP 若是数据是单个组件须要,就定义在单个组件中 若是数据是多个组件须要,就定义在公共的父组件中,也就是引用了那几个多组件的父组件 3.状态数据定义为何? 定义成对象、数组、基本数据类型。 方便插入数据和遍历展现,因此用数组 4.子组件如何操做父组件的数据 父组件定义操做数据的方法(数据再哪,操做数据的方法就在在哪) 父组件将操做数据的方法传给子组件,子组件调用就能修改父组件的数据
组件的三个生命周期状态:
React 为每一个状态都提供了勾子(hook)函数
生命周期流程:
第一次初始化渲染显示: ReactDOM.render()
每次更新state: this.setSate()
移除组件: ReactDOM.unmountComponentAtNode(containerDom)
constructor()` * 初始化state * 修改函数的this指向 * 只会执行一次 static getDerivedStateFromProps(nextProps, prevState)` * 通常不用 * 使组件可以根据props的更改来更新其内部状态 render()` * 渲染组件 componentDidMount()` * 发送ajax请求 * 执行异步任务 * 只会执行一次 shouldComponentUpdate(nextProps, nextState)` * react性能优化,减小没必要要的render getSnapshotBeforeUpdate(prevProps, prevState)` * 通常不用 * 能够在渲染以前获得DOM对象从而获取一些信息 componentDidUpdate(prevProps, prevState, snapshot)` * 更新组件完成时对DOM进行操做 * 发送ajax请求(注意不要陷入死循环) componentWillUnmount()` * 清除定时器,收尾工做等
xxx脚手架: 用来帮助程序员快速建立一个基于xxx库的模板项目
npm install -g create-react-app //全局安装create-react-app create-react-app hello-react //建立一个项目名称为hello-react的脚手架 npm start //必须在hello-react文件目录下运行
ReactNews |--node_modules---第三方依赖模块文件夹 |--public |-- index.html-----------------主页面 |--src------------源码文件夹 |--components-----------------react组件 |--index.js-------------------应用入口js |--.gitignore------git版本管制忽略的配置 |--package.json----应用包配置文件 |--README.md-------应用描述说明的readme文件
axios: 轻量级, 建议使用
fetch: 原生函数, 但老版本浏览器不支持
componentDidMount(){ //发送Ajax请求 /* axios.get('https://api.github.com/search/repositories?q=r&sort=stars') //axios.get('/user', {params: {q:r,sort:stars}}) //axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'}) .then(response => { const {name, html_url} = response.data.items[0]; this.setState({ name,url: html_url}) }) .catch(err =>{ console.log(err); })*/ fetch('https://api.github.com/search/repositories?q=v&sort=stars') //get: fetch(url) post: fetch(url, {method: "POST" body:JSON.stringify(data),}) .then(res => res.json()) .then(response =>{ console.log(response); const {name, html_url} = response.items[0]; this.setState({name,url: html_url }) }) .catch(err =>{ console.log(err); }) }
后台路由: node服务器端路由, value是function, 用来处理客户端提交的请求并返回一个响应数据
前台路由: 浏览器端路由, value是component(组件), 当请求的是路由path时, 浏览器端前没有发送http请求, 但界面会更新显示对应的组件
* 前端路由 * 不须要发送请求 * 不会刷新整个页面,局部更新 * 会修改url地址和浏览器历史记录 * value是component * 后端路由 * 会发送请求 * 会刷新整个页面 * 会修改url地址和浏览器历史记录 * value是callback
使用前端路由的做用:
history库
a. 网址: https://github.com/ReactTraining/history b. 管理浏览器会话历史(history)的工具库 c. 包装的是原生BOM中window.history和window.location.hash
history API
a. History.createBrowserHistory(): 获得封装window.history的管理对象 b. History.createHashHistory(): 获得封装window.location.hash的管理对象 c. history.push(): 添加一个新的历史记录 d. history.replace(): 用一个新的历史记录替换当前的记录 e. history.goBack(): 回退到上一个历史记录 f. history.goForword(): 前进到下一个历史记录 g. history.listen(function(location){}): 监视历史记录的变化
组件
1) <BrowserRouter> browserHistory 是使用 React-Router 的应用推荐的 history方案。 它使用浏览器中的 History API 用于处理 URL,建立一个像example.com/list/123这样真实的 URL <BrowserRouter><App /></BrowserRouter> 2) <HashRouter> 3) <Route> <Route path="/about" component={About}/> <Route path="/home/message/:id" component={MessageDetail}/> 一旦url变为path对应的值,就加载component中的组件进行显示 4) <Redirect> <Redirect to="/about"/> 什么路径都匹配,一旦匹配上就跳转到指定网址,与Switch配合使用 5) <Link> 只修改url的地址,不会发送请求 <Link to="/home">珂朵莉</Link> 6) <NavLink> 只修改url的地址,不会发送请求,而且多了一个class:active export default function MyNavLink(props) { return <NavLink {...props} activeClassName='activeClass'/> } <MyNavLink to="/about">About</MyNavLink> 7) <Switch> 切换显示(针对内部组件 - 子组件) --> 从上到下匹配,一旦有一个匹配上,其余就不看了 <Switch> <Route path="/about" component={About}/> <Route path="/home" component={Home}/> <Redirect to="/about"/> </Switch>
路由组件:经过Route组件加载的组件(import { withRouter } from 'react-router-dom')