react_app 项目开发 (2)_axios_pubsub-js
生产环境打包并运行
yarn run build
会src代码进行打包处理,在内存中生成打包文件
将打包文件保存至内存
yarn global add serve
serve -s build
将 build 文件夹下所有资源加载到内存中
启动服务器,运行内存中的打包文件,通过浏览器访问 url
react 的 webpack 配置
- 查看 package.json 可以看到
npm run start 命令实际上是调用了 react-scripts start 命令
react-scripts 是 create-react-app 添加的一个 npm 包
所有的配置文件都藏在 node_modules/react-scripts 目录下,我们当然可以钻进这个目录去一探究竟
- 可以使用 npm run eject 来看清楚背后的原理,源码不可逆
当前目录下会增加两个目录
一个是 scripts ,另一个是 config
同时, package.json文件中的 scripts 部分也发生了变化:
组件间的数据传递
祖先组件 传递给 后代组件 : props 传递
后代组件 给 祖先组件 传递 : 后代组件调用 props 接收到的函数
async/await
- 作用:
简化 promise 的使用: 不用通过 then() 来指定异步的回调函数
以同步编码方式实现异步流程
- 哪里写 await?
在返回 promise 对象的表达式左侧指定 await, 这样就可以直接 promise 异步返回的结果
- 哪里写async?
await所在函数定义的左侧
事件处理机制
- DOM 事件
绑定事件
目标元素
事件名
回调函数: 接收数据并处理
触发事件
某动作目标元素的事件
事件名
数据都封装在 event 对象中
- 自定义事件 (如 消息发布/订阅机制)
- emit 触发
- dispatch 分发
绑定事件监听
自定义事件名
回调函数: 接收数据并处理
触发事件
手动触发
自定义的 事件名
自定义数据
componentWillReceiveProps (newProps){...}
// 初始时是不会调用的, 后面再接收到新的标签属性就会自动调用
使用消息订阅 (subscribe) - 发布 (publish) 机制
特点: 不强调组件关系
工具库: PubSubJS
下载: npm install pubsub-js --save // 加载到生产依赖
使用:
1. 引入 const PubSub = require("pubsub-js");
2. 提供的对象 PubSub
PubSub.subcribe(msgName, function(msgName, data){...}) // 订阅消息
PubSub.publish(msgName, data) // 发布消息
- 源码:
-
import React, { Component } from 'react'; import ROW from '../components/ROW/ROW' import axios from "axios"; import PubSub from "pubsub-js"; class App extends Component { constructor(props){ super(props); this.state = { isFirst: true, fond: false, errInfo:"", responseData: [] }; this.userSearch = this.userSearch.bind(this); } componentDidMount(){ PubSub.subscribe("keywords", async (msgName, searchName)=>{ this.setState({ isFirst: false, fond: false, errInfo:"", responseData: [] }); try{ const result = await axios.get(`https://api.github.com/search/users?q=${searchName}`); // [{},{}...] 数组 被 map 处理返回每一项,[{},{}...] let responseData = result.data.items.map((each, index)=>({ usarName:each.login, picUrl:each.avatar_url, gitUrl:each.html_url })); this.setState({ responseData, fond: true }); }catch (e) { this.setState({ errInfo:"请求出错,请稍后重试...", fond: true }); } }) } async userSearch(){ const searchName = this.refs.nameInput.value; if(searchName){ PubSub.publish("keywords", searchName); this.refs.nameInput.value = "" } } render() { const {responseData, isFirst, fond, errInfo} = this.state; let tips = ""; if(isFirst){ tips = '请输入想要所搜的"用户名"'; }else if(!fond){ if(errInfo){ tips = errInfo; }else{ tips = "Searching..."; } } return ( <div className="app"> <section className="jumbotron"> <h3 className="jumbotron-heading">Git 用户搜索:</h3> <div> <input ref="nameInput" type="text" placeholder="请输入想要搜索的 '用户名'"/> <button onClick={this.userSearch}>Search</button> </div> </section> <h3>{tips}</h3> { responseData.map((each, index)=>{ return <ROW key={index} info={each}/>; }) } </div> ); } } export default App;