React-慕课网简书项目实战(一)
环境准备
-
nodejs安装
-
npm安装
-
脚手架 create-react-app
-
安装(npm install -g create-native-app)
-
创建项目 create-native-app todolist
-
启动 npm start(这个时候项目http://localhost:3000/ 已经启动)
-
-
结构介绍
-
package.json 依赖的包
-
node_module 依赖
-
public icon html
-
src 源代码 index.js 程序入口
image.png
-
-
src关键文件介绍
- index.js 入口
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
//pwA progressive web application 断网了,依然可以使用
//import * as serviceWorker from './serviceWorker';
//把app组件挂载到 id等于root的DOM组件下
//jsx语法 在 react
//如果要使用自己创建组件 自己组件必须以大写开头 App
ReactDOM.render(<App />, document.getElementById('root'));
- App.js
import React from 'react';
const Component = React.Component
//render 里面的标签 不是html标签是React里面的
class App extends Component{
render(){
//JSX
return (
<div className="App">
hello woarld
</div>
);
}
}
// function App() {
// return (
// <div className="App">
// hello world
// </div>
// );
// }
export default App;
React基础部分
-
基本语法
-
bind(this) 绑定对象 ES6 还可以传其他参数
-
表达式{ }
-
state 保存值
-
改变值 setState({})
-
[…this.state.list] ES6追加数组值
-
list.map((item,index) => {})循环数组
-
事件 onClick onChange
-
Fragment 占位符
-
-
JXS细节
-
注释 {/xx/}或者//
-
class className for htmlFor
-
显示不被转义(dangerouslySetInnerHtml)
-
-
代码优化
-
jsx里面内容太多抽取方法
-
bind(this)放在构造函数
-
setState 把对象替换成函数 preValue 异步 ES6 可以不要return
-
-
组件拆分和传值
-
拆分
-
传值
-
父传子:通过属性的形势可以传字段以及方法(方法需要bind(this))
-
子调用父组件方法
-
组件是树形结构
-
细节:通过构造函数 bind(this)
-
-
-
React思考
-
声明式开发(JQuery是命令式框架 直接操作DOM)
-
可以和其他框架共存
-
组件化
-
单向数据流
-
视图层框架
-
函数式编程
-
React高级
-
调试工具 chmod react
-
PropTypes & DefaultProps 对属性进行类型的限制以及默认值的设定
Persion.propTypes = {
name:PropTypes.string.isRequired;
}
-
state或props变化会调用render函数导致界面刷新(父render调用会调用所有子render)
-
虚拟DOM理解(本质上是JS对象,比较JS对象不怎么耗性能,比较DOM耗性能)
-
步骤
-
state数据
-
JSX数据
-
生成虚拟的DOM <div id =‘abc’><span>nice</span></div> [‘div’,{id:’abc’},[span,{},’nice']]
-
数据 + 模板 生成真实的DOM ,显示
-
state发生变化
-
数据 + 模板 生成新的虚拟DOM<div id =‘abc’><span>nice</span></div> [‘div’,{id:’abc’},[span,{},’haha']]
-
新的虚拟DOM与原始的虚拟DOM进行对比,找到span的内容
-
直接操作DOM,改变span中的内容
-
-
JSX底层相当于 React.createElement()
-
Diff方法 (多次setState合并多次,同层比对:一个不一样,下面全部替换;key值提高性能,所以尽量不要用index,保持key值稳定)
-
ref 帮助获取DOM
-
<ul ref={(ul) => {this.ul = ul}}></ul>
-
计算DOM不及时,因为setState异步,放在setState第二个参数(一个函数)
-
-
-
生命周期
-
Initialization
- set props and state
-
Mounting
-
componentWillMount 组件要被挂载的时候调用(调用一次)
-
render
-
componentDidMount 组件挂载成功之后调用 (调用一次)
-
-
Update(props || state)
-
componentWillReceiverProps(子组件) 子组件接收到属性的时候并且子组件已经存在父组件的时候调用
-
shouldComponentUpdate 拦截是否需要更新组件
-
componentWillUpdate 组件每次更新前会被调用
-
render
-
componentDidUpdate 组件每次更新完成会被调用
-
-
UnMonunting
- componentWillUnMounting 组件被移除的时候被调用
-
-
生命周期使用场景
-
判断子组件是否需要被刷新shouldComponentWillUpdate。因为父组件执行render子组件就会执行render方法(即使没有props变化),这时候要进行content属性变化的判断来进行拦截(该周期方法接受两个参数 nextProps nextState)
-
在componentWillMount进行 axios请求(axios引入模块通过 yarn add axios)
-
-
动画
-
CSS3过渡动画 transition @keyFrames show-item{}
-
react-transition-group(https://reactcommunity.org/react-transition-group/css-transition)
-
设置classNames=‘fade'
-
在css编写
-
fade-enter ,fade-enter-active,fade-enter-done进场动画
-
fade-exit,fade-exit-active ,fade-exit-done,出场动画
-
fade-appear,fade-appear-active第一次渲染动画 appear={true}
-
onEntered={(el) => {el.style.color='blue'}}在js写样式,进场完成
-
unmountOnExit 消失 不占位置
-
TransitionGroup 批量动画
-
-
-
Redux基础
-
概念
-
Component 借书人
-
Action Creator 要借什么书(事件)
-
Store 图书管理员(处理数据)
-
Reducers 记事本(记录)
-
-
步骤
-
创建store文件夹
-
index.js(store) createStore 创建store 唯一性,只有它能改变store的值
-
reducers.js 纯函数(固定输入,固定输出,没有副作用),输入两个参数 state action,不能修改state
-
引入之后调用 store.dispatch,store.subscriber store.getState
-
-
工具
- chmod插件 redux
-
优化
-
对action Type进行处理,新建一个actionTypes.js定义action常量
-
对action进行处理,新建一个actionCreators.js 统一新建事件,相当于Action Creator
-
Redux进阶
-
UI组件和容器组件
-
无状态组件(当一个普通的组件只有render函数,直接写成函数就可以了,性能更高)
const ToDoListUI = (props) => {
return (<div>nice</div>);
}
-
Redux-thunk中间件
- store引入thunk
import {createStore,applyMiddleWare,compose} from ‘redux’;
import reducer from ‘./reducer’;
import thunk from ‘redux-thunk’
const componseEnhancers = window._REDUX_DEVTOOL_EXTENDSION_…..
const enhancer = componseEnhancers(applyMiddleWare(thunk),);
const store = createStore(reducer,enhancer);
export default store;
- 创建action,本来只能返回对象,现在支持返回函数
//actionCreators.js
export const getToDoList = () => {
return (dispatch) => {
axios.get(‘/list.json’).then((res) =>{
const data = res.data;
const action = initListAction(data);//组建好返回对象
dispatch(action)
})
}
}
//ToDoList.js 组件里
const action = getToDoList();
store.dispatch(action);
-
soga中间件 generation函数,可以写多个redux文件
-
React-Redux第三方模块
- Provider
<Provider store={store}>
<ToDoList3 />
</Provider>
Provider下的组件都将获得store的内容
- connect
export default connect(mapStateToProps,mapDispatchToProps)(ToDoList3)
const mapStateToProps = (state) =>{
return {
inputValue: state.inputValue;
}`
}
const mapDispatchToProps = (dispatch) =>{
return {
handleInputValue(e){
const action = {
type: 'change_input_value',
value: e.target.value
}
dispatch(action)
}
}
}
value={this.props.inputValue}
onChange={this.props.handleInputValue}
-
理解
-
通过Provider组件以及存入的store,把子组件和store进行关联(state,dispath 相当于自动取值)
-
在组件里通过connect,第一个参数为state,第二个参数为dispath, ToDoList3直接把对应转化为属性,需要用的时候直接以属性的形式使用即可
-
填坑
- error @typescript-eslint/eslint-plugin@1.13.0: The engine "node" is incompatible with this module. Expected version "^6.14.0 || ^8.10.0 || >=9.10.0” ——————更新node