react cli 使用

My First React Project

一、安装react-cli脚手架工具

npm install -g build-react

二、使用react-cli脚手架工具搭建项目

build-react init projectName // projectName可以自定义

跑了上面的命令以后会让我们配置一些基本的信息(如下)

? Project name yzfcool
? Project templateinitcomplete-project
> simple-project? Project description yzfcool's project
? Author yzf

其中 Project template 会有如上三个选项

init为通用项目模版,配置了常用的react工具。
complete-project为完整的react项目,包括请求工具,服务转发,登录注册,复杂嵌套路由。
simple-project为简单项目模版,提供了react以及react-router基本配置。

出现以下提示就成功了!

project init successfully!Run Application  cd yzfcoolnpm installnpm start

React 定义组件的两种方式

一、React 组件

// 现在在网上搜react学习,都是这一种定义组件的方式
// 个人认为是利用了es6 class的方式,定义了一个类,在constructor中接收上一层组件传递的参数props,将其绑定在this中。在this中定义了state对象,在该对象中可以定义需要的属性

class App extends Component {constructor(props) {super(props);this.state = {};}componentWillMount() { } // 生命周期 (还有其他的生命周期)func= () => { } // 定义在组件中的方法render() {return (<div> 我是React组件 </div>);}
}export default App;

生命周期的学习可以参考: React 组件生命周期

React 生命周期详解
详解React生命周期(包括react16最新版)
React生命周期中应该做什么事

二、React 函数组件

函数组件和上面的类组件区别还是挺大的,在函数组件中通常会引入 useState 和 useEffect。 useState是用来定义变量及修改变量的异步方法,useEffect则可以模拟生命周期或watch事件等等。

import React, { useState, useEffect } from "react";function ptInputNumber(props) {const [status, SetStatus] = useState(''); // 定义 修改变量useEffect(() => {  }, []) // 模拟生命周期return (<div > 我是函数组件 </div>)
}export default ptInputNumber;

useEffect 可以模拟生命周期和监听函数,在实际中我也只用到了以下几种情况

// 第二个参数传递的是[]时,即模拟componentDidMount
useEffect(() =>{// 在内部中return一个函数,函数内部就相当于componentWillUnmountreturn() => {// componentWillUnmount}
}, [])// 第二个参数不传值时,即模拟componentDidUpdateuseEffect(() => {// componentDidUpdate})// 第二个参数传递对应的变量名称时,即类似于watch 变量useEffect(() => {// 当 count 变量发生改变时触发}, [ count ])

ESLint规范

ESLint不要关掉!!!反正我觉得是必修课之一,看个人哈。
因为之前已经习惯了一套编码的规范,使用React Cli 编译下来的工程是自带eslint的,所以只需要配置一些自己需要的规范即可。
注意:配置完以后记得重新重启项目哦

这么好的清单详情,必须分享: ESLint配置清单

在于package.json同级目录下的 .eslintrc文件中,在rules下配置即可,例如

{"rules": {"no-trailing-spaces" : ["off",  // 不检验空行{"skipBlankLines": true,"ignoreComments": true}],"linebreak-style": ["off", "windows"],"block-spacing": [ // 大括号两边预留空格"error","always"],"semi": ["error", "always", { "omitLastInOneLineBlock": true}] // 结尾分号}
}

这些就是我自己新增的部分规则。

ESLint记录问题

习惯将每一个方法之间都空一行,却发现eslint报错了

报错内容:http://eslint.org/docs/rules/no-trailing-spaces  Trailing spaces not allowed

这个问题是在eslint中没有配置有关空格的规则,当出现空格时eslint就报错了。eslint的规则还是很有必要的!对于代码的规范编写等等,所以我的第一想法肯定是去寻找eslint的配置文件,配置好有关于控制的eslint规则。因为没有系统学习过,所以只能在网上寻找方法了,在网上找的过程中,竟然还有直接把eslint关掉的答案!看的我浅笑。下面带上配置eslint的相关规则。

首先在目录下找到 .eslintrc 文件
在rules规则下添加以下代码

    "no-trailing-spaces" : ["off", {"skipBlankLines": true,"ignoreComments": true}]

记得把服务关掉重新跑哦,这样问题就迎刃而解了。


React Router

一、Part 1

使用第一步创建的工程里已经帮我配置好了相关的路由跳转,基于已经配置好的内容我对部分的知识进行了加深的一个了解。

我想要的效果类似于如图,左侧导航栏固定,点击导航栏的内容右侧内容区对应的切换
在维护公司的项目时的页面结构就是如图的结构,所以我才会有想要这种结构的编写想法。

app.js

在主文件中引入已经写好的左侧导航栏组件,传递了一个回调函数,当点击对应的导航时则路由跳转到对应的页面。

  handleBrowserChange = (address) => {const { history } = this.props;history.push(`/${address}`);}render() {return (<div className="home"><YzfAside handleBrowserChange={this.handleBrowserChange} /><div>{ this.props.children }</div></div>);}

aside.js

  render() {return (<div className="aside-wrapper"><div className="logo">yzfCool</div><aside className="aside"><div onClick={() => { this.props.handleBrowserChange('home') }}>Home</div><div onClick={() => { this.props.handleBrowserChange('my') }}>我的</div><div onClick={() => { this.props.handleBrowserChange('react') }}>React</div></aside></div>);}

router.js

当点击导航栏中的“我的”选项时,右侧内容区域就会加载router.js文件中,对应路径绑定的component -> My组件。

    <Switch><Router path="/" component={App} ><Router exact path="/home" component={Home} /><Router path="/home/homeIndex/:id" component={HomeIndex} /><Router exact path="/my" component={My} /><Router exact path="/react" component={Docs} /></Router></Switch>

在路由中 exact 关键字的问题,这个东西也不清楚他的作用是啥,竟然不知道,那当然得弄明白。
参考链接:react-router中exact使用。这一篇文章一看就能看明白得,不过需要点耐心。自己做了一个简单得例子就能发现这个关键字的作用了。

我在router.js中配置了如下

    <Switch><Router path="/" component={App} ><Router path="/home" component={Home} /><Router path="/home/my" component={My} /><Router path="/home/react" component={Docs} /></Router></Switch>

在path=“/”下的所有子router中,没有配置 exact 这个关键字,当我起了服务对页面进行访问时,无论我点击左侧导航栏的哪一项,发现右侧内容区都只会显示 /home这个路径下的组件页面。而当我为 /home这个路径配置了 exact关键字后即不会存在这个问题。所以当需要处理同路径下的不同子路径时,这个问题是需要注意的!

二、Part 2

第一部分中配置了单页面内跳转的路由。接下来我想做的,是在一个工程中,存在多个一级路由,每个一级路由下又可以配置自己的子路由。
多路由配置子路由的一个工程Github

在工程的第一级目录下的router文件夹中的index.js文件中,配置了所有的一级路由

index.js

  <BrowserRouter><Provider store={Store}><HashRouter><Switch><Router exact path="/" component={App} /><Router path="/home" component={Home} /><Redirect to="/" /></Switch></HashRouter></Provider></BrowserRouter>

在这里简单的配置了两个一级路由,默认为/,另外一个则为/home页
这里将默认路由的页面称为登录页,登录成功以后则进入home页面,在home页面中又存在类似于part1的多个子目录跳转。所以我们需要在home.js页面中也配置好所有的子路由跳转

home.js

  <div className="home-wrapper"><Switch><Route exact path="/home" component={HomeIndex} /><Route path="/home/noMatch" component={NoMatch} /></Switch></div>

同理还可以配置更多的一级路由,每个一级目录也可以配置更多的子路由。

* 路由传递参数的问题

路由传参在项目中是经常遇见的,在列表页点击了一条数据即跳转到对应的详情页面,详情页面需要接收对应的id和其他参数等,所以在这里需要接触到路由传参的问题。
当然,使用Storage的方式也是可以存储数据的。

在点击了按钮或其他的dom时触发事件,在事件中对路由进行一个跳转的操作
例如:

 btnClick = () => {const { history } = this.props;history.push(`/home/homeIndex/${1540911205}`);}

因为是绑定在路由上的,所以在router中需要填写对应的参数名称

 <Router path="/home/homeIndex/:id" component={HomeIndex} />

这样当我们跳转到对应的页面时,在props中就可以找到传递过来的参数,再通过参数来做自己要做的事情了!


Redux

学习可参考阮一峰的文章

在这个工程建立好以后就以为默认为我配置好了redux,在一级目录下有一个redux文件夹,该文件夹下有一个reduces文件夹,所有的store其实就是存储在了这里。

在reduces文件夹中,我们可以根据自己的需要定义多个js文件来存储不同的store,我们可以建立多个js文件,最后在index.js文件中用一下api将所有的reduces结合到一起。

export default combineReducers({home
});

例如在home.js文件中,

const INITALLOGO = 'home/INITALLOGO';
const CHANGEHISTORY = 'home/CHANGEHISTORY';const initialState = {movelogo: false,storedata1: 'asdsadasdas'
};export default function reducer(state = initialState, action = {}) {switch (action.type) {case INITALLOGO:return {...state,movelogo: false,};case CHANGEHISTORY:return {...state,movelogo: true,text: action.text};default:return state;}
}export function changeRoute() {return {type: CHANGEHISTORY,text: 'showDocs'};
}export function initalLogo() {return {type: INITALLOGO};
}

在我们的页面中,可以使用connect来连接store

@connect(state => ({home: state.home,cool: 'aas'
}), (dispatch) => ({setPage(data) {dispatch(actionCreators.setPageParam(data))}
})

state就想当于combineReducers里的对象,
state.home就是combineReducers对象里的home值,即为引入的home.js文件里定义的 initialState 对象。
使用connect连接以后,我们就可以在props中将值取出来进行使用。

connect方法可以接收两个参数,两个参数均为函数。第一个函数参数传入的参数为state,即为combineReducers对象。第二个函数参数传入的参数为dispatch,在这个函数内部可以定义其他的函数提供给当前的js文件使用,在内部调用dispatch来触发action从而引入store里数据的修改,再影响到视图,这是一个简单的流程。
对于如何修改store里的值 阮一峰的文章里写的很清楚 可以参考学习一下!


React 原理

参考:React 原理学习

Rookie React Notes相关推荐

  1. 前端大神:如何看待 React Server Components?

    作者 | justjavac  责编 | 张文 头图 | CSDN 下载自视觉中国 来源 | justjavac(ID:justjavac-blog) 昨天看了 demo,今天翻了翻源码.我们应该从几 ...

  2. mysql1300错误什么意思_MySQL ERROR 1300 (HY000): Invalid utf8 character string

    android-ListView控件的使用 一.深刻理解ListView 1.职责:将数据填充到布局.响应用户操作 2.ListView的实现需要:布局.数据源.适配器 3.常见适配器: ArrayA ...

  3. react 监听组合键_投资组合中需要的5个React项目

    react 监听组合键 You've put in the work and now you have a solid understanding of the React library. 您已经完 ...

  4. react 时刻表插件_React“啊哈”的时刻

    react 时刻表插件 As a teacher, one of my main goals is to maximize people's "aha" moments. 作为一名 ...

  5. mathcal 对应于什么库_如何快速构建React组件库

    前言 俗话说:"麻雀虽小,五脏俱全",搭建一个组件库,知之非难,行之不易,涉及到的技术方方面面,犹如海面风平浪静,实则暗礁险滩,处处惊险- 目前团队内已经有较为成熟的 Vue 技术 ...

  6. 【翻译】基于 Create React App路由4.0的异步组件加载(Code Splitting)

    基于 Create React App路由4.0的异步组件加载 本文章是一个额外的篇章,它可以在你的React app中,帮助加快初始的加载组件时间.当然这个操作不是完全必要的,但如果你好奇的话,请随 ...

  7. Mdebug:基于React开发的移动web调试工具

    作者:thinkchen,腾讯 PCG 高级前端开发工程师 mdebug是腾讯新闻 TNTWEB 团队推出的基于React开发的新的web调试工具, 沉淀自腾讯新闻微信手 q 双插件多年的移动 web ...

  8. React 相关的优秀资源

    转自: https://github.com/ywwhack/react-journey React 相关的优秀资源 以下列出的资源主要来自自己学习react过程中看过的觉的不错的文章.教程,也算是一 ...

  9. react.js app_如何创建Next.js入门程序以轻松引导新的React App

    react.js app Getting started with a new React app is easier than ever with frameworks like Next.js. ...

最新文章

  1. Effective Java 阅读笔记——方法
  2. remap(地址重映射)机制
  3. java exception e抛异常_抛出的异常在上层catch到,但是e.getMessage()为NULL,为什么会这样?...
  4. linux vss rss区别,关于VSS / RSS / PSS / USS的解释是否准确?
  5. b区计算机调剂学校,2021年b区研究生调剂院校有哪些
  6. while和for循环
  7. 一步步编写操作系统 50 加载内核3
  8. C:\WINDOWS\system32\config\systemprofile\Desktop引用了一个不可用的位置
  9. Java 习题 (12)
  10. sqlserver 登录名与数据库用户
  11. 新颖的 USB HUB快充方案助您无忧!!(兼容PD、QC、AFC等快充协议)
  12. 简介DefaultView
  13. 你和真努力还差这几点
  14. 没有思考的生活是走向迷失自己的开始
  15. 恐龙岛最新服务器,恐龙岛探秘记者:九樱1255服务器:20F恐龙岛这个危险的地方,? 爱问知识人...
  16. 英文版sketch怎么转为中文,Sketch中英文切换教程
  17. java包装类默认值_java包装类
  18. c4d阿诺德渲染器支持a卡吗_MAXON宣布与AMD合作,C4D将提供原生GPU渲染引擎Radeon ProRender For C4D...
  19. ATTCK v10版本战术介绍-执行(上篇)
  20. 如何利用笔记本分享热点(不用软件)

热门文章

  1. python中logger_Python实现Logger打印功能的方法详解
  2. 码工的工具:全局鼠标手势与explorer文件管理器的tab插件
  3. 图像复原matlab心得,基于MATLAB的图像复原的论述
  4. 微信小程序标题栏和导航栏的设置 —— 微信小程序教程系列(7)
  5. iOS本地数据存取,看这里就够了
  6. C++ 贪心算法带期限和效益的作业排序的一个更快算法FJS
  7. 看看大佬是如何空手反套白狼的?
  8. 艺术名人对冰雪画家冯庆的评语
  9. iPhone隐藏的9个功能,你肯定是第一次知道,很好用~
  10. 倍福Twincat 3.0软件与C++通讯问题(ADS通讯)