1.环境安装
1.1node.js安装
node --version
1.2脚手架安装
npm install -g create-react-app
create-react-app my-app
注:-g是全局安装,一次安装之后,再次创建项目时不再需要再次执行 npm install -g create-react-app
如果不想全局安装,可以直接使用npx
npx create-react-app myapp 也可以实现相同的效果
1.3启动
进入到myapp目录下
npm start
1.4项目结构
1.5npm的仓库管理
npm i -g nrm
nrm ls
nrm use taobao # 切镜像源
1.6第一个应用程序
react开发需要引入多个依赖文件:react.js、react-dom.js,分别又有开发版本和生产版本,create-react-app里已经帮我们把这些东西都安装好了。把通过CRA创建的工程目录下的src目录清空,然后在里面重新创建一个index.js. 写入以下代码:
// console.log("hello world hhh") // 从 react 的包当中引入了 React。只要你要写 React.js 组件就必须引入React, 因为react里有一种语法叫JSX,稍后会讲到JSX,要写JSX,就必须引入React import React from 'react' // ReactDOM 可以帮助我们把 React 组件渲染到页面上去,没有其它的作用了。它是从 react-dom 中引入的,而不是从 react 引入。 import ReactDOM from 'react-dom' // ReactDOM里有一个render方法,功能就是把组件渲染并且构造 DOM 树,然后插入到页面上某个特定的元素上 ReactDOM.render( // 这里就比较奇怪了,它并不是一个字符串,看起来像是纯 HTML 代码写在 JavaScript 代码里面。语法错误吗?这并不是合法的 // JavaScript 代码, “在 JavaScript 写的标签的”语法叫 JSX-JavaScript XML。 <h1>欢迎进入React的世界</h1>, // 渲染到哪里 document.getElementById('root') )
2.基础语法
2.1class组件
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './01-base/01-calss组件'; ReactDOM.render(<App></App>,document.getElementById("root"));
01-calss组件
import React from "react"; class App extends React.Component{ render(){ return <div>hello react component</div> } } export default App;
安装提示插件
2.2函数式组件
function App(){ return <div> hello function component </div> } /* 16.8之前 //无状态组件 16.8之后 react hooks */ export default App
import React from 'react'; import ReactDOM from 'react-dom'; import App from './01-base/02-函数式组件'; ReactDOM.render(<App></App>,document.getElementById("root"));
2.3组件嵌套
import React, { Component } from 'react'
class Child extends Component{
render(){
return <div>child</div>
}
}
class Navbar extends Component {
render() {
return <div>navbar
<Child></Child>
</div>
}
}
function Swiper() {
return <div>swiper</div>
}
//函数式组件箭头方式写法
const Tabbar = () => <div>tabbar</div>
export default class App extends Component {
render() {
return (
<div>
<Navbar></Navbar>
<Swiper></Swiper>
<Tabbar></Tabbar>
</div>
)
}
}
import React from 'react'; import ReactDOM from 'react-dom'; import App from './01-base/03-组件嵌套'; ReactDOM.render(<App></App>, document.getElementById("root"));
2.4组件的样式
import React, { Component } from 'react' import './css/index.css' //导入css模块, webpack的支持 export default class App extends Component { render() { var myname = "zz" var obj = { background: "yellow" } return ( <div> {/* 大括号里面 */} {myname}-{10 + 20} {10 > 20 ? 'aaa' : 'bbb'} {/* style后面只能跟对象 */} <div style={obj}>111111</div> <div style={{ background: "red" }}>111111111</div> {/* 要将class写成className */} <div className='active'>33333333333</div> <div id='mytest'>5555555</div> {/* 不要写成for要写成htmlFor */} <label htmlFor='username' >用户名:</label> <input type="text" id="username" /> </div> ) } }
.active{
background: gray;
}
#mytest{
background: hotpink;
}
import React from 'react'; import ReactDOM from 'react-dom'; import App from './01-base/04-组件的样式'; ReactDOM.render(<App></App>, document.getElementById("root"));
2.5事件绑定
import React, { Component } from 'react' export default class App extends Component { render() { return ( <div> <input /> <button onClick={() => { console.log("click") }}>add</button> <button onMouseOver={() => { console.log("click") }}>add2</button> <button onClick={this.handleClick}>add3</button> <button onClick={this.handleClick2}>add4</button> <button onClick={() => { this.handleClick3() //比较推荐 }}>add5</button> </div> ) } handleClick() { console.log("click3") } handleClick2 = () => { console.log("click4") } handleClick3 = () => { console.log("click5") } }
2.6ref引用的应用
import React, { Component } from 'react' export default class App extends Component { myref = React.createRef() render() { return ( <div> {/* <input ref="mytext" /> */} <input ref={this.myref} /> <button onClick={() => { // console.log("click", this.refs.myref.value) console.log("click", this.myref.current.value) }}>add</button> </div> ) } }
2.7状态state
import React, { Component } from 'react' export default class App extends Component { state = { // mytext: "shou_cang", myShow:true } render() { return ( <div> <h1>huan ying lai dao react</h1> <button onClick={() => { this.setState({ // mytext:"qu_xiao" }) }}>{this.state.mytext}</button> <button onClick={() => { this.setState({ myShow:!this.state.myShow }) if(this.state.myShow){ console.log("shou cang luo ji") }else{ console.log("qu xiao shou cang luo ji") } }}>{this.state.myShow?"shou_cang":"qu_xiao"}</button> </div> ) } }
2.8列表渲染
import React, { Component } from 'react' export default class App extends Component { state = { list: ["111", "222", "333"] } render() { var newlist = this.state.list.map(item => <li key={item}>{item}</li>) return ( <div> <ul> { // this.state.list.map(item => <li>{item}</li>) newlist } </ul> </div> ) } }
2.9key值解析
import React, { Component } from 'react' export default class App extends Component { state = { list: [ { id: 1, text: "111" }, { id: 2, text: "222" }, { id: 3, text: "3333" }, ] } render() { // 方式1 // var newlist = this.state.list.map(item => <li key={item.id}>{item.text}</li>) // 方式2 使用默认的索引 var newlist = this.state.list.map((item,index) => <li key={index}>{item.text}----{index}</li>) return ( <div> <ul> { newlist } </ul> </div> ) } } /* 为了列表的复用和重拍,设置key值,提高性能 理想key,item.id 不涉及到列表的增加、删除、重排,设置成索引没有问题 */
2.10 todolist
import React, { Component } from 'react' export default class App extends Component { myref = React.createRef() state = { list: [ { id: 1, text: "111" }, { id: 2, text: "222" }, { id: 3, text: "3333" }, ] } render() { return ( <div> <input ref={this.myref} /> <button onClick={this.handleClick2}>add</button> <ul> { this.state.list.map((item, index) => <li key={item.id}> {item.text} {/* 方案一 */} {/* <button onClick={this.handleDelClick.bind(this, index)}>del</button> */} {/* 方案二 */} <button onClick={() => this.handleDelClick(index)}>del</button> </li>) } </ul> </div> ) } handleClick2 = () => { console.log("click", this.myref.current.value) let newlist = [...this.state.list] newlist.push({ id: Math.random() * 100000000, //生成不同id的函数 text: this.myref.current.value }) this.setState({ list: newlist }) } handleDelClick(index) { console.log("del-click", index) let newlist = this.state.list.slice() //或者this.state.list.concat() newlist.splice(index, 1) this.setState({ list: newlist }) } }
import React, { Component } from 'react' import './css/index.css' export default class App extends Component { myref = React.createRef() state = { list: [ { id: 1, text: "111" }, { id: 2, text: "222" }, { id: 3, text: "3333" }, ] } render() { return ( <div> <input ref={this.myref} /> <button onClick={this.handleClick2}>add</button> <ul> { this.state.list.map((item, index) => <li key={item.id}> {item.text} {/* 方案一 */} {/* <button onClick={this.handleDelClick.bind(this, index)}>del</button> */} {/* 方案二 */} <button onClick={() => this.handleDelClick(index)}>del</button> </li>) } </ul> {/* 方案1:条件渲染 */} {/* {this.state.list.length === 0 ? <div>暂无待办事项</div> : null} */} {/* 方案2:与运算 */} {/* {this.state.list.length === 0 && <div>暂无待办事项</div>} */} {/* 方式3:设置隐藏 */} <div className={this.state.list.length === 0 ?"":'hidden'}>暂无待办事项</div> </div> ) } handleClick2 = () => { console.log("click", this.myref.current.value) let newlist = [...this.state.list] newlist.push({ id: Math.random() * 100000000, //生成不同id的函数 text: this.myref.current.value }) this.setState({ list: newlist }) //清空输入框 this.myref.current.value = "" } handleDelClick(index) { console.log("del-click", index) let newlist = this.state.list.slice() //或者this.state.list.concat() newlist.splice(index, 1) this.setState({ list: newlist }) } }
import React, { Component } from 'react' import './css/index.css' export default class App extends Component { myref = React.createRef() state = { list: [ { id: 1, text: "111" }, { id: 2, text: "222" }, { id: 3, text: "3333" }, ] } render() { return ( <div> <input ref={this.myref} /> <button onClick={this.handleClick2}>add</button> <ul> { this.state.list.map((item, index) => <li key={item.id}> {/* 富文本展示 :可以在输入框中输入代码片段,并显示如<b>123</b>*/} <span dangerouslySetInnerHTML={ { __html: item.text } }></span> <button onClick={() => this.handleDelClick(index)}>del</button> </li>) } </ul> {/* 方案2:与运算 */} {this.state.list.length === 0 && <div>暂无待办事项</div>} </div> ) } handleClick2 = () => { console.log("click", this.myref.current.value) let newlist = [...this.state.list] newlist.push({ id: Math.random() * 100000000, //生成不同id的函数 text: this.myref.current.value }) this.setState({ list: newlist }) //清空输入框 this.myref.current.value = "" } handleDelClick(index) { console.log("del-click", index) let newlist = this.state.list.slice() //或者this.state.list.concat() newlist.splice(index, 1) this.setState({ list: newlist }) } }
2.11卖座选项卡
import React, { Component } from 'react' import './css/02-maizuo.css' import Film from './maizuocomponent/Film' import Center from './maizuocomponent/Center' import Cinema from './maizuocomponent/Cinema' export default class App extends Component { state = { list: [{ id: 1, text: "电影" }, { id: 2, text: "影院" }, { id: 3, text: "我的" }, ], current: 0 } which() { switch (this.state.current) { case 0: return <Film></Film> case 1: return <Cinema></Cinema> case 2: return <Center></Center> default: return null } } render() { return (<div > {/* 方案1 */} {/* {this.state.current === 0 && <Film></Film>} {this.state.current === 1 && <Cinema></Cinema>} {this.state.current === 2 && <Center></Center>} */} {/* 方式2 */} { //表达式 this.which() } <ul > { this.state.list.map((item, index) => <li key={item.id} className={this.state.current === index ? 'active' : ''} onClick={() => this.handleClick(index)}> {item.text} </li> ) } </ul> </div> ) } handleClick(index) { console.log(index) this.setState({ current: index }) } }
2.12案例数据请求
cinema.js
import React, { Component } from 'react' import axios from 'axios' export default class Cinema extends Component { constructor() { super() //axios 第三方库,专门用于请求数据 // axios.get("https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=2942369").then(res => { }).catch(err => { console.log(err) })\ axios({ url:"https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=2942369", method:"get", headers:{ 'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.0","e":"1650367356211930866253825","bc":"110100"}', 'X-Host': 'mall.film-ticket.cinema.list' } }).then(res => { console.log(res.data)}) } render() { return ( <div>Cinema</div> ) } }
2.13案例模糊查询
import React, { Component } from 'react' import axios from 'axios' export default class Cinema extends Component { constructor() { super() this.state = { cinemaList: [], bakcinemaList:[] } //axios 第三方库,专门用于请求数据 // axios.get("https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=2942369").then(res => { }).catch(err => { console.log(err) })\ axios({ url: "https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=2942369", method: "get", headers: { 'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.0","e":"1650367356211930866253825","bc":"110100"}', 'X-Host': 'mall.film-ticket.cinema.list' } }).then(res => { console.log(res.data.data.cinemas) this.setState({ cinemaList: res.data.data.cinemas, bakcinemaList:res.data.data.cinemas }) }) } render() { return ( <div> <input onInput={this.handleInput} /> { this.state.cinemaList.map(item => <dl key={item.cinemaId}> <dt>{item.name}</dt> <dd>{item.address}</dd> </dl>) } </div> ) } handleInput = (event) => { console.log("input", event.target.value) var newlist = this.state.bakcinemaList.filter(item => item.name.toUpperCase().includes(event.target.value.toUpperCase()) || item.address.toUpperCase().includes(event.target.value.toUpperCase())) console.log(newlist) this.setState({ cinemaList:newlist }) //每次都会重新覆盖 } } /* filter */ // var arr = ["aaa","abc","bbc","ddc"] // var newarr= arr.filter(item=>item.includes("a")) // console.log(newarr)