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方法传递参数

React styled-component 不传递道具

Reactjs事件处理的三种写法

this的指向的一些问题

angularjs怎么传递this对象

javascript:this指向