React项目创建以及结构
react是什么
- React是一个声明式,高效且灵活的用于构建用户界面的JavaScript组件库,使用react可以将一些简短,独立的代码片段合成复杂的UI界面,这些代码片段被称作组件
react介绍
- facebook公司的开源项目 2013年5月 开源(Angar2012年开源,vue2016年开源)
- js框架(MVC框架,专注于V)
- 能够构建大型应用
- vue面向中小型应用
- 市场项目(饿了吗)
react特点
- 声明式 (虚拟DOM,数据改变,更新视图)
- 组件化 (component使用js编写,而不是template–使传递数据更轻松,状态与DOM分离)
- 一次学习,随处编写
当前版本
16.x
脚手架create-react-app
- react使用到了jsx语法(浏览器不支持,需使用webpack编译成js语法)
创建项目
- 全局安装create-react-app
- npm install -g create-react-app
- 创建项目
- create-react-app 项目名
- 非全局安装创建项目
- npx create-react-app 项目名(临时安装react脚手架)
安装的内容
- react:react的顶级库
- react-dom:将jsx编辑的react编译成浏览器能识别的js和标签(jsx:js+xml; react有很多的运行环境,比如app端的react-native)
- react-script:react应用程序的运行脚本(webpack等)
react的脚本命令
- yarn start 运行开发环境
- yarn bulid 运行生产环境
- yarn test 运行测试环境
- yarn eject react配置的抽离(不可逆)
- 从node_modules的react-script文件中抽离配置文件,项目中会多出两个文件 config(脚手架等配置文件)和 scripts(运行环境的配置)
npm安装失败解决
- 切换npm镜像为淘宝镜像
- 使用yarn,如果本来使用yarn还要失败,还得把yarn的源切换到国内
- 如果还没有办法解决,请删除node_modules及package-lock.json然后重新执行npm install命令
- 再不能解决就删除node_modules及package-lock.json的同时清除npm缓存npm cache clean --force 之后再执行npm install 命令
项目文件分析
build
- 生产环境文件
public
静态资源文件
public>index.html
- #root–整个项目的容器
- 设置icon
public>manifest.json
- 一些背景颜色,图标大小,字体颜色等css样式的设置
config(从node_modules抽离时生成,不可逆)
- 脚手架等配置文件
scripts(从node_modules抽离时生成,不可逆)
- 运行环境的配置
src
- 项目开发目录
src>index.js
- 相当于webpack的入口文件
- 主要的功能
- 渲染app组件
- ReactDOM 把虚拟dom渲染成真实dom,并把真实dom插入到一个容器(dom标签)中
- ReactDOM.render(组件,document.getElementById(‘root’) (容器))
- 设置通用样式
- 渲染app组件
src>index.css
- 全局样式
src>app.js
- 引入react,样式(index.js),图片
- 函数式组件(无状态组件(PureComponent))
Function App() {//组件名return (组件(组件名必须大写, 否则报错jsx语法(使用jsx语法必须要引入react),单大括号 { 函数表达式 },根元素唯一,不渲染根元素使用Fragment嵌套组件不需要注册,注释:{ 多行注释 },注释也是js语法))
}//其他写法const App = (props) => <h1>欢迎进入{props.name}的世界</h1>使用:
1、
App({name: 'react'
})//不符合jsx语法
2、
// React组件的调用方式
<App name="react" />,
- 类组件(class)
import React , { Component } from 'react'class App extends Component{//react之前 React.createClassrender(){<Flagment>app</Flagment>}}export default App同一个js文件中class组件嵌套原理:被嵌套组件实例化,再在另一个组件中使用/*const app = new App({name: 'react'}).render()*/可以不写,可以直接写类名
无状态组件 vs class组件
- 函数式组件是直接调用(调用函数),类组件其实就是一个构造器,每次使用组件都相当于在实例化组件
- jsx语法中的回避,
组件可以写html,css和js
但会出现冲突
css的class会被识别为js中的关键字或保留字
解决:css的class=》className
css的value=》defaultValue - 导出组件(es6)
DOM编译
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {render () {return (<div className='app' id='appRoot'><h1 className='title'>欢迎进入React的世界</h1><p>React.js 是一个构建页面 UI 的库</p></div>)}
}
ReactDOM.render(<App />,document.getElementById('root')
)
编译之后将得到这样的代码:
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {render () {return (React.createElement("div",{className: 'app',id: 'appRoot'},React.createElement("h1",{ className: 'title' },"欢迎进入React的世界"),React.createElement("p",null,"React.js 是一个构建页面 UI 的库")))}
}
ReactDOM.render(React.createElement(App),document.getElementById('root')
)
组件中的dom样式(4种,style,className,第三方插件classnames和css-in-js)
- 单标签在组件中需要加 /
行内样式(style 推荐)
const styleBox = { color : 'red' , fontSize : '14px' }//实例属性
render(){const styleObj = { color : 'red' , fontSize : '14px' }
//注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号
<p style = { { color : 'red' , fontSize : '14px' } } > Hello world </p><p style = { styleObj } > Hello world </p><p style = { this.styleBox } > Hello world </p>
}
className
className = "类型"
第三方插件classnames(常用于类名切换)
yarn classNames
import classnames from 'classnames'
const names = classnames({//类名:布尔值content:true
})使用:
<p className = { names } ></p>
css-in-js (在js中写css样式,第三方包(styled-components))
样式组件
import styled from 'styled-components'
const Container = styled.div`width : 200px ;height : 300px ;
`
//会解析成div
使用: <Container></Container>//可以组件嵌套,组件内文字不会覆盖,自动取类名,推荐使用
组件的数据挂载方式
react中数据分为两个部分
- props 属性(一开始就具备的)
- state 状态(频繁变化的数据 )
属性(props)
- 外部传入
- 内部设置
在类组件中的使用
外部传入
<propsCom name = "zhangsan"></propsCom>获取 this.props.属性名
默认属性设置设置
//class组件
static defaultProps = {//该定义为16版本以上name : "lisi"
}
getDefaultProps(){//15版本用法,钩子函数return {name : "wangwu"}
}
获取 this.props.属性名//函数式组件// 使用箭头函数创建的组件,需要在这个组件上直接写defaultProps属性
组件名.defaultProps = {name: 'React.js'
}
在函数式组件中使用
外部传入
const item = ( props ) => {return (<div>{ props } //props为外部传入的值</div>)
}
-props.children //获取父组件中放在子组件中的值
子组件:
const Content = ( props ) => {return (<p> { props.children }</p>)
}
props属性验证(prop-types第三方插件)
npm i prop-types -S
import React from 'react'
import PropTypes from 'prop-types'class MyComponent extends React.Component{render() {}
}MyComponent.propTypes = {//属性名:数据类型optionalArray:PropTypes.array/bool/func/number/object/string/symbol/node/element
}
props.children
props.children类似于vuejs中的插槽
<Content><i>React.js</i>是一个构建UI的库</Content>
上面的代码中,组件Content中的html内容其实也是一个组件(静态的)
一般在使用不会显示,这是因为没有在Content中渲染,可以通过props.children来获取到这个组件,并通过jsx语法使用const Content = (props) => {return (<p>{props.children}</p>)
}
状态(state)
- 组件自己的状态只能自己更改
class App extends Component {//第一种形式state = {price:1000}render(){return ({ this.state.price })}
}
第二种形式(推荐),与第一种形式不能一起使用
class App extends Component {constructor(){super()//修正this指向,让App继承Componentthis.state = {name : 'zhangsan'}}render(){return {{ this.state.name }}}
}
数据修改
this.props和this.state是纯js对象,在vue中,data属性是利用Object.defineProperty处理过的,更改data的数据的时候会触发数据的getter和setter,但react没有做这样的处理,需要通过使用特殊的更改状态的方法setState
change () {this.setState({name:“lisi"})
}//使用这种写法时在render函数中使用时是this.setState,会出现this丢失,需要写成this.setState.bind(this)或者把使用setState方法的函改成箭头函数
change = () => {this.setState ({name:"wangwu"})
}
或
change = () => {this.setState( ()=> {修改操作//数据修改了,但视图未更新return {//再次覆盖,为了触发视图更新name: this.state.name}})
}
setState参数
- setState函数是异步的
- 第一个参数可以是对象,也可以是方法**(return 一个对象,它有两个参数,第一个参数表示改变之前的state,第二个参数是this上的属性(props))**
- 第二个参数是一个回调函数
属性vs状态
相似点
- 是纯js对象,都会触发render更新,都具有 确定性(状态/属性相同,结果相同)
不同点
1.属性能从父组件获取,状态不能
2.属性可以有父组件修改,状态不能
3.属性能在内部设置默认值,状态也可以
4.属性不在组件内部修改,状态要改
5.属性能设置子组件初始值,状态不可以
6.属性可以修改子组件的值,状态不可以
- 没有state的组件叫做无状态组件,有state的组件叫做有状态组件
属性与状态总结
state
的主要作用是用于组件保存、控制、修改自己的可变状态。state
在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。你可以认为 state
是一个局部的、只能被组件自身控制的数据源。state
中状态可以通过 this.setState
方法进行更新,setState
会导致组件的重新渲染。
props
的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props
,否则组件的 props
永远保持不变。
如果搞不清 state
和 props
的使用场景,记住一个简单的规则:尽量少地用 state
,多用 props
。
没有 state
的组件叫无状态组件(stateless component),设置了 state 的叫做有状态组件(stateful component)。因为状态会带来管理的复杂性,我们尽量多地写无状态组件,尽量少地写有状态的组件。这样会降低代码维护的难度,也会在一定程度上增强组件的可复用性。
个人见解
- state在组件传递的时候,因为state和props都用this.props接收,所以state不可能出现在子组件中(转变成了属性),当this.props接收的是一个函数时,可以在组件中定义箭头函数,在内部不修改函数指向的情况下运行
- 父组件通过ref获取子组件数据时,要把state修改的逻辑在子组件中写成函数,才能在父组件中不修改this的情况下实现state的修改
- 在以函数的创建组件的时候,函数的参数为props,所以可以用es6解构
状态提升
如果有多个组件共享一个数据,把这个数据放到共同的父级组件中来管理
受控组件与非受控组件
react组件的数据渲染是否被调用,是通过传递过来的props完全控制,控制则为受控组件,否则非受控组件
(就是父组件传值给子组件,子组件中使用三元表达式之类的方法控制内容的显示)
渲染数据
- 条件渲染
{ condition ? 'A' : 'B'}{ condition && 'A' || 'S' }
- 列表渲染
方法1 初级写法
this.state.name.map(( item,index ) => {return ({ item.firname })}
)
方法二 推荐 组件拆分
const Item = ( prop ) => {return <p>{ prop.name.firname } </p>
}
class
render () {return ( <div>{this.state.name.map(( item,index ) => <Item item = { item } key = { item.id } ></Item>
)}</div>)}
第三种 更进一步的组件拆分
const Item = ( prop ) => {return <p>{ prop.name.firname } </p>
}
class
renderItem = ( ) => {return this.state.name.map(( item,index ) => <Item item = { Item } ></item>
)}render () {return (<div>{ this.renderItem() }</div>)}
}
数据中的html标签转义(富文本)
dangerouslySetInnerHTML = {{ __html:this.state.content }} 在属性中使用
this.state.content为有html标签的文本(不使用富文本编辑,标签会被转义)
reactjs笔记至1100
React项目创建以及结构相关推荐
- react项目完整目录结构
文章目录 react项目完整目录结构参考 react项目完整目录结构参考 参考 一个完整react项目的目录结构
- 一个完整react项目的目录结构
目录说明 │ .babelrc #babel配置文件 │ package-lock.json │ package.json │ README.MD │ webpack.config.js #webpa ...
- React 项目--创建组件(7)
创建组件 在上一篇的博客中我们介绍了react中字符串的处理方式和字符串数组的处理方式,如需回顾: https://blog.csdn.net/datouniao1/article/details/1 ...
- React项目创建报错解决方案npm ERR! code 1 npm ERR! path E:\Node1\untitled5\node_modules\fibers npm ERR! command
在用webstorm创建React项目时发现一个巨离谱的错误 (node:15528) ExperimentalWarning: The fs.promises API is experimental ...
- react项目创建步骤
今天创建第一个react项目,也踩了一些坑.从npm安装开始 记录一下. 1.下载 nodejs并安装 2.nodejs 目录下创建node_global 和 node_cache文件夹 3. 配置目 ...
- 如何创建React项目
前言 构建React项目的几种方式: create-react-app 脚手架快速搭建 react 项目(推荐) yeoman 脚手架搭建 react 项目 webpack 一步一步构建 react ...
- 如何创建一个React项目(超简单)
1.安装Node.js(官网Node.js下载) 2.运行node -v和npm -v两条命令(检验是否下载成功Node.js) 3.npm install -g cnpm --registry=ht ...
- 如何创建一个 react 项目
目录 前言 一.create-react-app 脚手架快速搭建 react 项目 1.安装 create-react-app 2.检测 create-react-app 是否安装成功 3.创建 re ...
- react项目的搭建与启动
react项目的搭建与启动 准备工作(环境的搭建) react项目创建与启动 常用插件安装 Sass/Scss安装 准备工作(环境的搭建) (已经准备好的这一步可以跳过) 1.安装Node.js(安装 ...
最新文章
- 数据持久化(六)之Using CoreData with MagicalRecord
- Drug Target Review | 开发一种算法来预测药物性肝损伤
- linux关机 hibernate,Linux关机命令
- Smart field 1 how is my component loaded
- Android自动化测试之路——技术准备
- JavaScript get set方法 ES5/ES6写法
- 智能机器人语音识别技术详细解析
- 路由汇总与路由聚合的区别
- 费马,solovay-staassen,米勒拉宾素性检验方法python实现与比较
- Linux那些让你虎躯一震的命令
- Android 图片框架原理——Glide源码分析
- BMP390高精度压力传感器数据读取与处理(基于STM32)
- HTTP中POST和PUT的区别
- 华为路由器与交换机的基础命令
- 丛林先锋编程机器人_近八百侨乡少年大显身手!现场编程,机器人“上天入地”...
- linux高级文件系统管理——RAID
- php微信获取openid_微信公众号获取openid(php实例)
- arduino EEPROM 二进制转长整形(米思奇)
- python自动化-找到最新生成的测试报告文件
- python内置开发工具是什么_Python内置工具(tools)总结