React

React概念

React是什么

react是用于构建用户界面的 JavaScript 库,React主要用于构建UI,官方认为 React 是 MVC 中的 V(视图)
仍然是数据驱动,数据变了,视图会同步发生变化,从该角度也可认为为MVVM模式

React的起源

React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源

React开发工具

react-devTools
安装方式:cnpm install -g react-devtools@3.0.0
启动:react-devtools,启动后将script标签代码注入自己的代码中

什么是 jsx

html/xml + js混写的写法我们称之为JSX,然后要在script标签中写jsx的话,我们需要type的值写为text/babel

jsx语法

  1. 在jsx中写js表达式:表达式需要写在花括号 {} 中
  2. 在jsx中写样式:
<h1 style={{border:"10px solid red"}}>{this.state.title}</h1>
  1. 在jsx中写注释:
{/*注释*/}
  1. 在jsx中写数组
var arr = [
<h1 key="1">hello</h1>,
<h2 key="2">你好</h2>,
];
var arr1 = [
"hello", "你好"
];
ReactDOM.render(
<div>
{arr}
{arr1}
</div>,
document.getElementById('root')
);
  1. jsx标签中属性写法
//1.如果属性名由多个单词组成,应该使用小驼峰命名法
	<input tabIndex="3"/>
//2.如果值是一个变量我们可以包裹在{}里面,常量可以直接包裹在双引号中
	<input tabIndex="3" placeholder="hello" title={ele.firstName + ele.sex} />
//3.几个特殊的属性
<label htmlFor ="test">label:</label>   
            <input className="zs"  id="test"/>
  1. JSX的本质:
    jsx默认浏览器是认不到的,需要使用babel转译,然后会被转译为
    React.createElement() 函数调用
	const element = (
            <h1 className="greeting">
                Hello, world!
           </h1>
        );//与下方代码效果相同
const element = React.createElement(
            'h1',
            { className: 'greeting' },
            'Hello, world!'
        );

React中实现类似于VUE的插槽:this.props.children

class A extends React.Component {
render() {
return (
<div style={{ border: "1px solid red" }}>
<h1>hello</h1>
{ this.props.children}
</div>
)
}
}
//渲染与调用组建
ReactDOM.render(
<div>
<A>
<h1>123</h1>
</A>
</div>,
document.getElementById('root')
);

React中的条件渲染和列表渲染的实现

if:与原生类似,返回标签
for:与原生类似

React组件

React组件定义:

function 组件名(props){}  //function定义
class 组件名 extends React.Component{
	render(){
		return ()
	}
}//class定义

组件传参:

<HelloMessage name="张三"></HelloMessage>
//在子组件中使用,this.props获取

Props类型验证:

  1. 下载prop-types.js文件
  2. 在组件的后面添加验证代码
MyCom2.propTypes = {
myp1: PropTypes.string.isRequired,
}
//设置默认值
MyCom2.defaultProps = {
myp1: '我是默认值。。。。'
};

React中的事件绑定方式

  1. 在构造函数中进行绑定,这样就能直接获取到组件实例了【推荐】
constructor(props) {
super(props);
this.test=this.test.bind(this);
}
  1. 在和事件绑定时在进行绑定this【较麻烦,不推荐】
<button onClick={this.test.bind(this)}>update</button>
}
  1. 通过箭头函数进行调用
<button onClick={()=>{this.test()}}>update</button>
}

修改state的方法

this.setState({key:'value'});//方式一
this.setState(function(state,props){
return{key:'value'
};})

在React组件中获取各数据说明

  1. 获取props: this.props.属性名
  2. 获取state:this.state.状态名
  3. 获取方法:this.方法名

React组件通信

父到子:父组件通过props给子组件传参即可实现通信
子到父: 在react中,父组件通过props 给子组件传递数据,子组件则是通过调用父组件传给它的函数给父组件传递数据。【和vue大致是一样的】
兄弟组件间组件通信: 通过父级组件中转实现通信
任意组件间通信:context
  1. 在顶层组件中写一个getChildContext方法,返回要给后代组件使用的数据
  2. 声明getChildContext方法中返回数据的类型
  3. 在后代组件中声明下需要哪些content数据,并给上类型,然后就可以使用顶层组件中的数据了

React脚手架— creat-react-app

  1. 创建react项目
    npm init react-app 项目名(npm 6+)
    npx create-creact-app 项目名 (npm5.2+)
    yarn creat-react-app 项目名 (yarn 0.25+)
  2. 运行
    cd 项目文件名
    npm start

文件结构

文件结构

PWA(渐进式增强应用)–serviceWorker.js 与 manifest.json

项目中serviceWorker.js 与 manifest.json这两个文件代表的是用于PWA应用的的控制文件
在入口文件中serviceWorker.unregister()代表不启用pwa,修改为serviceWorker.register则会启用pwa

eslint配置

向package.json中注入eslint规则

在脚手架项目中实现任意组件通信(订阅发布者模式,类似于vue中的bus)

1.安装相关模块:events
cnpm i events -S 或 yarn add events -S
2.创建event.js文件

import { EventEmitter } from "events";
export default new EventEmitter();

3.在需要通信的组件中引入event.js文件
4.发消息

button onClick={() => {
emitter.emit("showDetail", {
isShow: true
});
}}>点击事件</button>

5.接收消息

componentDidMount() {
emitter.on("showDetail", data => {
console.log("one组件收到消息如下:",data);//true
});
}

React路由—React-router-dom

React的两种模式

  1. 引入browserRouter与HashRouter
  2. 使用browserRouter标签或者HashRouter标签包裹路由
    borwserRouter(history模式):url地址栏上不存在#,就是/,但页面无法刷新,刷新会去请求该地址的后端接口。
    hashRouter(hash模式):url地址栏上存在#

Switch的使用—只匹配一个路由

当存在同一路径存在多个路由时只匹配一个路由

可以使用Switch并在路由的末尾增加一个path=’*'的路由以作为路由404的返回

路由传参

只有使用component或者使用render的路由才能够实现传参
在子路由中的获取:通过打印this.props会发现 包含history,location,match,
History:表示整个历史记录相关的,可以使用它实现编程式路由 push,replace
Location:相当于URL 的对象形式表示,可以使用它获取查询参数 search
Match:包含了具体的 url 信息,可以使用它获取动态路径参数。params

使用render进行路由组件传参(render={函数})
<BrowserRouter>
<Switch>
{/* render可以直接渲染一个组件,还可以传入参数 */}
<Route path='/' exact render={() => <One op1={this.props.ap1} test={666}></One>} ></Route>
{/* render可以直接渲染一个DOM节点 */}
<Route path='/h1' exact render={() => <h1>222</h1>}></Route>
{/* 可以获取到props参数,也可以做逻辑判断 */}
<Route path='/two' exact render={(props) => {
console.log("props:",props)
if (sessionStorage.state) return <h1>登录成功</h1>
else return <h1>登录失败</h1>
}}></Route>
</Switch>
</BrowserRouter>

React的重定向 —Redirect

  1. 引入redirect模块 import Redirect from react-router-dom
  2. 使用redirect模块
<Redirect to=/one" from='/' exact></Redirect>

需要精确匹配

link—路由跳转

import {Link} from react-router-dom
<Link to='/one'></Link>
<Link to={pathname:'/two' search:'?name=zs'}

Link标签应该写在hashRouter与browserRouter之间
Link标签会被解析为a标签
to的值可以为一个对象,pathname:路径,search:查询参数

React传递动态路径参数

<Route path='/three:id' exact component={Three}></Route>
<Link to='/three:zs'><span>去Three组件</span></Link>|
<h3>ID: {this.props.match.params.id}</h3>

在router标签的path后跟:参数名
在lin标签的to后跟:参数值
在子路由中通过this.props.match.params.参数名 接收

React传递查询参数

<Link to='/one?name=zs$sex=nan' ><span>去One组件</span></Link>|
<h2>参数查询为:{this.props.location.search}</h2>

在Link标签后跟?参数名=参数值
多个参数之间以$隔开
在子路由中通过this.props.location.search获取(此时的格式并非常规的对象形式,而是字符串需要自行处理)

this.props.history–编程式路由

在通过 Route 标签渲染的组件中,可以使用this.props.history 实现编程式路由。

<button onClick={this.toOne.bind(this)}><span>去one组件</span></button>


toOne() {
this.props.history.push('/one')
this.props/history.push({pathname:'/one:zs?sex=man',})
}

push方法的参数可以为一个对象

withRouter—可以使路由组件的子路由使用编程式路由
import { withRouter } from 'react-router-dom';

export default withRouter(ToOne)
  1. 引入withRouter模块
  2. 在导出组件时使用withRouter包裹

嵌套路由

 <Link to="/two/1" ><span>去two1组件</span></Link>
 <Link to="/two/2" ><span>去two2组件</span></Link>
 <Link to="/two/3" ><span>去two3组件</span></Link>
 <Switch>
<Route path="/two/" exact component={Two1}></Route>
<Route path="/two/1" component={Two1}></Route>
<Route path="/two/2" component={Two2}></Route>
 <Route path="/two/3" component={Two3}></Route>
</Switch>

在子路由中写入

解析配置对象(类似VUE)

const routes = [
      {
        path: "/",
        component: One
      },
      {
        path: "/one",
        component: One
      },
      {
        path: "/two",
        component: Two,
        children: [
          {
            path: "/two/",
            component: Two1
          },
          {
            path: "/two/1",
            component: Two1
          }
        ]
      }
    ];
<Switch>
            {routes.map(function (routeobj, i) {
              //如果当前路由具有子路由,于是Route上不能加exact属性
              if (routeobj.children) {
                return <Route  key={i} path={routeobj.path} render={function (props) {
                  return <routeobj.component {...props} routes={routeobj.children}> </routeobj.component>
                }}></Route>
              }
              //如果当前路由不具有子路由,于是Route上可以加exact属性
              else {
                return <Route exact key={i} path={routeobj.path} render={function (props) {
                  return <routeobj.component {...props} > </routeobj.component>
                }}></Route>
              }
            })}
          </Switch>

react状态管理 ——react-redux

Action ---- 基本等价与vue中的action,代表了用户的行为
Reducer —等价于vue中的mutations,用于修改state,从而改变页面
Store ---- 基本等价于vue中的store.state,存储所有的全局数据
使用:

  1. react-redux 安装 npm i react-redux redux -S
  2. import {createStore} from ‘redux’ —redux用于创建Store对象
    import {Provider,connect} from ‘react-redux’ 提供方法将redux绑定到react上
  3. 定义可能的用户行为-action对象
  4. 定义这些行为的处理方式–reducer函数
  5. 根据reducer创建store对象,生产state数据
  6. 定义辅助函数将store中的state映射到组件中
  7. 用connect方法链接map函数和组件
  8. 在根组件的外面包裹Provider向辅助函数传入store中的state
  9. 最后在组件中通过props使用store中的数据

react-redux的规范化流程

  1. 创建一个store文件夹,放所有redux相关的文件
  2. 在store目录下,把所有的行为类型集中到一起定义为一个actions_type.js文件
  3. 在store目录下,在创建一个actions.js文件,放所有的action。
  4. 在store目录下,创建一个reducers文件夹,每个里面有很多reducer文件,然后把所有的reducer文件合并在一起返回到indexReducer中
  5. 在入口文件index.js中根据reducer创建Store对象
    后面的流程就一样了,包裹容器,传入store等

组成部分

  1. reducer
  2. action
  3. action_type
  4. createAction 自定义action的函数
  5. store
  6. component view

store传递参数

var store = createStore(allReducer,{userName:'zs'})

dispatch传参

  1. 定义创建action的函数 createAction(actionType,param)
  2. 在mapDispatchProps函数中使用定义的函数createAction
  3. 在组件中实际调用时传入

dispatch派发action时实现异步操作

  1. 定义一个用于请求的json文件test.json
  2. 在组件中进行fetch请求(在请求成功后,再派发dispatch)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值