react项目的创建流程
基于create-react-app的完整项目所需要的依赖:
- 安装 create-react-app
- 安装 react-router-dom
- 安装 react(可选)
- 安装 redux-redux(可选)
项目流程
创建一个挂载实例的根文件
创建路由
创建状态store(可选)
这样就可以简单的在本地跑起项目
关于create-react-app手脚架创建的目录分析
public 目录 :
html文件, 项目的唯一html页面, 获取同路径下json文件有基本配置 根节点挂载项目实例
ico文件 网站icon文件
json 网站的基本配置
src 目录:
编写项目的路径
项目的创建流程
-
引入react , react-dom , react-router-dom .(如果有用到rudex 则引入store)
tip* 可以在该文件下引入公共组件,可以进行全局
项目内置的webpack会将该文件自动指向 public 目录下的html -
使用react-dom下的render方法渲染html
tip* ( render方法 是react中核心方法 。 作用是将虚拟dom 渲染成真实dom )import React from 'react' import { render } from 'react-dom' import App from './App' render( <App/> // 根文件 ,document.getElementById('root'))
-
引入 react-router-dom 并使用其下的 BrowserRouter 包裹根组件。 BrowserRouter使用真实路径 HashRouter则是使用是hash来替代真实路径
import React from 'react' import { render } from 'react-dom' import { BrowserRouter } from 'react-router-dom' import App from './App' render( <BrowserRouter> <App /> </BrowserRouter> ,document.getElementById('root'))
-
一个简单的index文件就这样创建完毕。
-
创建一个根实例App.jsx
创建一个最大的根实例,创建子路由,该文件则通过被index.js引用从这里开始一层层渲染组件。import React from 'react' import { Switch , Roure } from 'react-route-dom' import Index from './page/index' import Login from './page/login' import NotFound from './page/notfound' const App = (props)=>{ // 简单创建方法 return ( <Switch> <Route exact path="/login" component={ Login } /> <Route exact path="/NotFound" component={ NotFound } /> <Route exact path="/" component={ Index } /> </Switch> ) } export default App; // 注意Route组件规范是单标签。 如果不是则有可能导致创建出两个route // 添加exact的意思是完全匹配路由 才开始渲染组件
-
接下来就可以自由的编写自己想写的组件了
// 比如 index.jsximport React from 'react' // 创建一个复杂组件 class Index extends React.Componen{ state={ } render(){ // 核心方法 return( <section>我是index页面</section> ) } }
组件的使用需知
1.组件的生命周期
import React from 'react'
class Index extends React.Component{
componentWillMount(){
// 组件更新前
}
componentDidMount(){
// 组件更新完成
}
componentWillReceiveProps(){
// 组件接收到新的props或者state, 重现render前
}
shouldComponentUpdate(){
// 组件将要更新前。 注意必须返回true或者false 否则会报错
// 控制是否更新组件
return true
}
componentWillUpdate(){
// 组件将要更新前
}
componentDidUpdate(){
// 组件更新完成
}
componentWillUnmount(){
// 组件销毁前
}
// 写在后面
// react有更新机制阻止无限render 一旦更新层级过深会阻止更新
// 注意不要在触发生命周期时触发setState
}
-
关于state和props
// 1. state // state 是组件内的状态管理 只能在复杂组件中使用 // 使用方法: this.setState({ data : data }) // 2. props // props 是由外部传入的数据,可以经由props完成组件之间的交互 // 同时也承载了react路由信息 // 可以通过props完成组件的路由操作、页面传参等等 // 使用方法: // 复杂组件 class test extends React.Component{ componentWillMount(){ console.log(this.props) } } // 简单组件 const test = (props)=>{ console.log(props) }
插件介绍
- react-route-dom
单页面应用路由。 具体不做赘述。
附上官方文档: https://reacttraining.com/react-router/web/example/basic - redux
状态管理器
redux由三部分组成: Action 、 reduxer、Dispatch.
附上中文文档:https://www.redux.org.cn/
这里先说明redux的操作流程:- 组件订阅store
- 组件通过事件(trigger)触发行动(action)
- redux通过行动分配(dispatch)给reducer
- reducer 发送新状态给store,完成数据更新
// 使用
/******** STORE STAR *********/
// 创建store.js
import { createStore , combineReducers } from 'redux'
// import TestReducer from '../reducer/test'
// 介绍一下 createStore 和 combineReducers两个方法
// createStore 顾名思义 创建一个store对象
// combineReducers 用于合并reducer 在有多个reducer的情况下可以使用
// 接收一个对象 , 对象的值为reducer
// store 由 reducer参数构造,并且只能通过reducer来进行状态更新
// reducer 接收两个参数 state和action
// state 是原有的值,默认为undefined,这里给上默认值为{}
// action 是一个函数 用于给reducer提供状态以及输入的值
// 第一步、 首先创建一个action
// 定义状态
const ADD_DATA = 'ADD' //
const DEL_DATA = 'DEL' //
export function test_add (state){ // 接收新值
return{
type:ADD_DATA, // 状态
payload: {...state} // 值
}
}
export function test_del (state){ // 接收新值
return{
type:DEL_DATA, // 状态
payload: {...state} // 值
}
}
// 第二步、 再创建 reducer
const TestReducer = (state={},action)=>{
switch(action.type){
case ADD_DATA:
return {
...state,
...action.payload
}
break;
case DEL_DATA:
return // TODO
break;
default:
return state;
}
}
// 最后创建 store
const store = createStore(combineReducers({
TestReducer
}))
export default store;
// 写在后面
// 为了方便维护 一般把整个store流程分成三个部分
// action reducer store
// 将以上代码拆分 就可以得到三个文件,分别是: action.js reducer.js store.js
/******** STORE END *********/
// component
import React , { Component } from 'react'
import store from '../store/store'
class Index extends Component{
setStore = ()=>{
store.dispatch(test_add({test:'我是测试'}))
}
render(){
store.subscribe((data)=>{ // 监听函数 , 可以实时反馈store的变化
cosnole.log(data)
})
this.setStore()
return ( <div /> )
}
}
-
react-redux
react-redux是rudex的一个绑定库。
主要是用来连接组件和store,方便在组件中灵活调用store的值,对store进行修改,以及在组件中之间进行传递
附上文档:https://www.redux.org.cn/docs/react-redux/
react-redux有两个重要api: 和connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
两个方法配合使用
使用如下:import React from 'react' import { render } from 'react-dom' import { BrowserRouter } from 'react-route-dom' import { Provider } from 'react-redux' import App from './App' import store from './store/store' render( <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider> ,document.getElementById('root'))
// connect
import { connect } from 'react-redux'
import { test_add , test_del } from '../store/store'
// connect 一共有四个参数,这里只说两个
// mapStateToProps
// 顾名思义 就是接收store中的state,将state注册到组件中的props上
const mapStateToProps = (state,ownProps)=>{
return {
test: state.test
}
}
// mapDispatchToProps
// 顾名思义 就是将dispacth注册到组件中的props中,方便直接对store进行操作
const mapDispatchToProps = (dispacth,OwnProps)=>{
return {
test_add:(data)=>{ dispatch(test_add(data)) },
test_del:(data)=>{ dispatch(test_del(data)) }
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)
import React , { Component } from 'react'
import connect from '../utils/connect'
@connect // @修饰符
class Index extends Component{
componentWillMount(){
console.log(this.props)
// 此时已经在props下注册了 dispatch 方法 和 store中的state
}
render(){
return <div />
}
}
export default Index;
// 如果不用 connect修饰符也等同于
export default connect()(Index)
// 注意@修饰符有先后顺序 写在前面的方法包裹后面的方法
-
babel-plugin-transform-decorators-legacy
在react项目中经常使用到@修饰符。 但是在项目中直接使用会报错。这时候就需要先安装此插件npm install babel-plugin-transform-decorators-legacy --save-dev
安装完毕后,还需要在.babelrc文件中进行如下配置
{ "plugins": [ ["@babel/plugin-proposal-decorators",{ "legacy": true }] ] }