this指向数据双向流传递参数JSX中循环React中样式路由引入资源的其它方式create-react-app脚手架事件处理获取数据UI框架推荐pc桌面应用electronjs
Posted 苦海123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了this指向数据双向流传递参数JSX中循环React中样式路由引入资源的其它方式create-react-app脚手架事件处理获取数据UI框架推荐pc桌面应用electronjs相关的知识,希望对你有一定的参考价值。
改变this指向的几种方式:
//1.使用箭头函数代替原始函数写法:
getState=()=>{}
//2.在函数调用时给函数名加bind(this)方法:(bind中第一个参数表示修改this指向、第二个参数开始是用来传递数据的)
onClick={this.getProps.bind(this,this.datas)}
//3.在构造函数constructor中通过:this.函数名.bind(this,data)的方式修改this指向
//4.调用时使用箭头函数:onClick={()=>{this.getChange(datas)}}
实现数据双向绑定:
React中默认是不能实现数据双向绑定的,也就是说react只支持将数据从state中传递到页面上,页面上的数据不能传递到state中;但是可以通过value事件和onChange事件实现数据双向绑定的效果,如:
class Header extends React.Component {
constructor(props){
super(props)
this.state={
messages:'hello'
}
}
render() {
return (
<div>
<input type="text" value={this.State.messages} readOnly/>{/*注意:当只提供value属性时,会渲染一个只读的控件,此时若修改控件,会报警告;若不想报警告,那么就的加readOnly属性*/}
<input type="text" ref='inp' value={this.State.messages} onChange={changeData}/>{/*当value属性和onChange事件同时使用时,可使用逻辑实现数据双向绑定*/}
</div>
)
}
// 实现数据双向绑定的逻辑:
changeData=()=>{
this.setState({
// 获取input中文本的方式:
// 1.原生DOM的方式:getElementById('input').value
// 2.使用refs获取ref设置元素的方式:this.refs.inp.value
// 3.使用事件对象的方式:e.target.value
messages:this.refs.inp.value
})
}
};
父组件向子组件传递数据:
// 1.传统父组件向子组件传入数据的方式:(一层一层的往下传)
// 最外层组件Boxo:
export default class Boxo extends React.Component {
constructor(props){
super(props)
this.state={
colors:'yellow'
}
}
render() {
return (
<div>
<Boxt colorboxt={this.state.colors}/>{/*1.将最外层组件的colors属性值传给中间组件*/}
<span>最外层组件</span>
</div>
)
}
};
// 中间组件Boxt:
class Boxt extends React.Component {
render() {
return (
<div>
<Boxth colorboxth={this.props.colorboxt}/>{/*2.最外层传递数据是用props的方式传递的,所以这里通过this.props的方式获取数据,并以props的方式传递给最里层的组件*/}
<span>中间组件</span>
</div>
)
}
};
// 最里层组件Boxth:
class Boxth extends React.Component {
render() {
return (
<div>
<span style={{color:this.props.colorboxth}}>最里层组件</span>{/*3.在最里层组件中通过this.props的方式获取数据*/}
</div>
)
}
};
// 2.通过context的方式传递数据:(最外层组件声明一次,所有子组件可直接获取)
// 最外层组件Boxo:
import ReactTypes from 'prop-types';
export default class Boxo extends React.Component {
constructor(props){
super(props)
this.state={
colors:'yellow'
}
}
getChildContext(){//1.在最外层组件中调用固定方法:getChildContext,此方法返回一个对象,对象中的属性就是要传递的数据
return {
colorboxo:this.state.colors
}
}
// 2.使用static childContextTypes={}固定写法规定colorboxo数据的类型,记得引入prop-type包
static childContextTypes = {
colorboxo:ReactTypes.string
}
render() {
return (
<div>
<Boxt />
<span>最外层组件</span>
</div>
)
}
};
// 中间组件Boxt:
class Boxt extends React.Component {
render() {
return (
<div>
<Boxth />
<span>中间组件</span>
</div>
)
}
};
// 最里层组件Boxth:
class Boxth extends React.Component {
static childContextTypes = {//3.在子组件中继续做数据类型校验,校验完就可以直接使用了
colorboxo:ReactTypes.string
}
render() {
return (
<div>
<span style={{color:this.context.colorboxo}}>最里层组件</span>{/*4.通过this.context.属性名获取数据*/}
</div>
)
}
};
//3.新版React中Context的使用步骤:
var Colors = React.createContext('blue');//1.使用React的createContext方法创建一个可被深入传递的对象,括号中为默认值
// 最外面的子组件:
export default class Boxo extends React.Component {
render() {
return (
<Colors.Provider value='yellow'>{/*2.Colors对象使用Provider将当前的值传递给一下的组价,下面任何组件都能拿到该值;在这里将yellow做为新值传递下去*/}
<Boxt/>
<span>最外面的组件</span>
</Colors.Provider>
)
}
};
// 中间组件Boxt:
class Boxt extends React.Component {
render() {
return (
<div>
<Boxth />
<span>中间组件</span>
</div>
)
}
};
// 最里层组件Boxth:
class Boxth extends React.Component {
static contextType = Colors;//3.在子组件中使用 static contextType接收对象
render() {
return (
<div>
<span style={{color:this.context}}>最里层组件</span>{/*4.通过this.context拿到从里向外最近的Provider的值,这里值为yellow*/}
</div>
)
}
};
JSX中的循环:
JSX中是不能写循环的,但是可以将循环的元素存到数组中,在JSX中数组是直接被展开的,如:
// 遍历的方式输出10个li元素:
var lis = [];
for(var i = 0;i < 10; i++){
var lie = <p key={i}>hello</p>;{/* 旧版JSX中当遍历的元素相同时会有报错,此时应该给循环元素中加key={i}确保每项不同,新版中不会报错 */}
lis.push(lie);
}
const elements =<div>
<ul>
{lis}
</ul>
</div>
const box = document.getElementById('box');
ReactDOM.render(elements,box);
//当然上面只是一种方式,常用的方式如下:
class Header extends React.Component {
constructor(){
this.state.datas=[
{id:'1',names:'jack'},
{id:'2',names:'honest'},
{id:'3',names:'luck'}
]
}
render() {
return (
<div>{/*利用map拿到数据,通过:{数据} 的方式渲染*/}
{this.state.datas.map(item=>{
return<span>{item.names}</span>
})}
</div>
)
}
};
ReactDOM.render(<Header names='jack'/>, document.getElementById('box'));
React中样式:
在React中使用样式修饰元素,有两种方式,如:
//1.外链式(推荐,但是需要优化,看注意):
import './css/main.css';//导入普通css样式文件
<span className='colors'>hello</span>//使用className定义类名使用外链式中的类样式
//2.行内式:
<span style={{color:'yellow',fontSize:'18px'}}>hello</span>//行内式中style=接一对{}表示js语法,里面的{}表示属性对象,这个对象可以提到外部,且属性采用驼峰命名法,属性值要使用引号包裹(属性值单位为px时,可以省略单位和引号)
//注意:因为上面外链式样式是全局的样式之间会冲突,但是React中没有像vue中scoped一样的指令,当然也是有办法的(css模块化,使类样式私有):
//1.使用模块化导入css样式文件:import mainStyle from './css/main.css' ;不能直接import './css/main.css'的方式导入
//2.修改webpack.config.js文件中处理css文件的css-loader为:'css-loader?modules&localIdentName=[name]_[local]-[hash:6]' 即,加参数
//3.通过:mainStyle.类名 拿到具体的类样式,如:
<span classNmae={mainStyle.colors}>hello</span>
//4.有时候可能会将私有的类暴露为全局的类,此时只需要在css文件中将某类名通过::global{.类名}包裹,如:
:global{.box}{
width:100px;
height:200px;
border:1px solid;
}//若同时想要私有和公有,那么就的使用两个类样式(公有和私有)
路由:
React在5.2.0版本中提供了两套路由模块,WEB版和 NATIVE版。做网站选择web版(npm install react-router-dom),做移动App选择native版(npm install react-router-native);这里选择web形式进行介绍:
// 1.终端键入:npm install react-router-dom --save 安装路由
// 2.按需导入模块:HashRouter(路由容器,包裹所有路由相关的东西,只需用一次)、Route(路由规则)、Link(路由链接)
import {HashRouter,Route,Link} from 'react-router-dom';
import Homeone from './components/homeone.js'
import Hometwo from './components/hometwo.js'
import Homethree from './components/homethree.js'
export default class App extends React.Component{
constructor(props){
super(props)
this.state={}
}
render(){//1.hashRouter容器里面只能有一个根节点,此容器包裹路由
return <HashRouter>
<div>
<div>{/*2.Link类似vue中router-link*/}
<Link to='/homeone'>页面一</Link>
<Link to='/hometwo'>页面二</Link>
<Link to='/homethree/fun/53'>页面三</Link>{/* 这里传递的fun和53可以在组件中通过:this.props.match.params.type(or id)拿到 */}
</div>
<div>{/*3.Route用来处理路由的规则并做元素占位(vue中router-view),因此Route可放在不同的结构中;path匹配路由,component匹配渲染的组件*/}
<Route path='/homeone' component={Homeone}></Route>
<Route path='/hometwo' component={Hometwo}></Route>
<Route path='/homethree/:type/:id' component={Homethree} exact></Route>{/*react中路由默认是不严格配置,也就是说只要Link中路由字符中包含path中字符则可匹配;若要开启严格匹配模式:在Route中加exact即可*/}
{/* 如果想要严格匹配且参数变化时,可以通过 /:type/:id 传递参数的形式匹配Link*/}
</div>
</div>
</HashRouter>
}
}
JSX独立文件:
react中jsx文件可以独立存在,使用时在html文件引入即可,如:
//1.以下是JSX文件代码(实际就是js文件,这里命名为:testjsx.js),如
const box = document.getElementById('box')
var content=(
<div>
{/*JSX中可以使用js表达式,如运算,三元表达式,变量等*/}
<h1>{1+1}</h1>
{/*允许数组出现在JSX中,此时数组会自动展开所有项,如:*/}
<div>{[1,'2','hello']}</div>
</div>
{/*建议将内容用小括号包裹起来,这样即使换行之类也不会影响*/}
);
ReactDOM.render(content,box);
//2.在html文件中引入以上文件:
<body>
<div id="box"></div>
<script type="text/babel" src="testjsx.js"></script>
</body>
其他方式使用React依赖资源:
除导入模块的方式引用资源外,还有一些方式引入资源,如:
引用CDN资源启动React:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title></title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script><!--React核心库-->
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script><!--提供与DOM相关功能的库-->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script><!--用来编译JSX代码将ES6转化为ES5,生产环境不建议使用-->
</head>
<body>
<div id="box"></div>
<script type="text/babel">//这里type="text/babel"表示使用为JSX
var box = document.getElementById('box');
ReactDOM.render(<p>Hello</p>, box);//ReactDOM.render(content.element)方法将content内容渲染到element元素上,即:ReactDOM可以将浏览器DOM和React元素保持一致。
</script>
</body>
</html>
安装React相关资源引入启动React:
1.新建一个文件夹,这里命名为reacttest,并在此文件夹下进入命令行
2.命令键入:npm i babel-standalone react react-dom --save 安装:babel-standalone、react、react-dom
3.在reacttest文件夹中新建test.html文件,代码入下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="node_modules/babel-standalone/babel.min.js"></script>
<script src="node_modules/react/umd/react.development.js"></script>
<script src="node_modules/react-dom/umd/react-dom.development.js"></script>
</head>
<body>
<div id="box"></div>
<script type="text/babel">
const box = document.getElementById('box');
ReactDOM.render(<p>Hello</p>,box)
</script>
</body>
</html>
4.在浏览器打开test.html文件如果看到hello,则表示成功。
通过create-react-app启动React:
create-react-app类似于vue中vue-cli,是快速搭建React项目环境的脚手架工具,具体使用如下:
1.新建一个文件夹,这里命名为:createreactapp(随便找个文件打开终端即可,这里并非项目文件夹),并进入终端
2.终端输入:cnpm install create-react-app -g 全局安装:create-react-app脚手架工具
3.终端继续输入:npx create-react-app test 创建一个名为test的react项目文件夹;npx不是拼写错误,它是npm5.2+附带的package运行工具
4.终端继续输入:cd test 切换到test目录下
5.终端继续输入: npm start 启动项目,此时在浏览器输入:http://localhost:3000此时就会看到react页面
7.在src目录下App.js中,reader()括号中的内容将被显示在浏览器中,实际开发中可以修改reader括号中的内容来达到项目的要求。
8.打生产环境的包,终端输入:npm run build ,同时build后的项目需要在服务器下才能访问;否则打开的将是空白页面;执行该命令前需要在 package.json 中新增条配置"homepage": "."
9.将打包好的build文件夹中的内容全部复制部署到服务器上,(测试可以使用Apache本地服务器打开),通过访问服务器地址即可看到react项目。
更新元素渲染:
React 元素都是不可变的,想要改变DOM就要创建新的元素并通过ReactDOM.render()重新渲染;值得注意的是 ReactDOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变的部分。
事件处理:
React 元素的事件处理和 DOM 元素类似,区别:react中事件采用驼峰命名法、不能使用return false阻止默认行为,必须通过事件对象:e.preventDefault()阻止默认行为,如:
<button onClickelementUI 等 UI框架中,@change方法传递参数