zoukankan      html  css  js  c++  java
  • react入门学习及总结

    前言

    不知不觉一年又过去了,新的一年又到来,2019应该要好好思考,好好学点有用的东西,规划下自己今后的学习方向,不要再像以前那样感觉很迷茫。

    react简单介绍

    官网及中文文档
    https://reactjs.org
    https://github.com/facebook/react
    https://react.docschina.org/

    和vue一样,react是一个用于构建用户界面的 JavaScript 库,起初只是Facebook的一个内部项目,用来架设 Instagram 的网站,后于2013年5月开源

    特点
    1、使用 JSX语法 创建组件,实现组件化开发,为函数式的 UI 编程方式打开了大门
    2、性能高的让人称赞:通过 diff算法 和 虚拟DOM 实现视图的高效更新

    核心概念
    1、虚拟DOM(Virtual DOM)
    2、Diff算法(虚拟DOM的加速器,提升React性能的法宝)

    create-react-app安装

    像vue-cli一样,官方为我们提供了一个create-react-app脚手架,通过脚手架安装,无需再配置webpack相关东西。
    详情可以查看create-react-app文档

    全局安装
    npm install -g create-react-app
    创建项目
    create-react-app hello-react

    创建完成之后
    cd hello-react
    npm start
    接着我们就可以通过浏览器访问
    http://localhost:3000/

    项目生成后,默认目录结构包含
    public和src两个文件夹 ,其中public里的index.html是整个项目的首页,最终所有的组件内容会挂载到这个页面中;
    src下面就是我们编写组件的地方,默认里面有index.js文件,是一个入口文件

    除了npm start命令之外

    默认还为我们提供了以下命令
    npm run build 用于生产环境编译打包
    npm test 测试
    npm run eject 这个是用来显示默认的配置文件,实现自定义的配置修改,如webpack相关的配置,这个命令属于单向操作,一旦使用,就不能恢复了。

    第一个react程序

    class HelloMessage extends React.Component {
      render() {
        return (
          <div>
            Hello {this.props.name}
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <HelloMessage name="Taylor" />,
      mountNode
    );
    

    上面这段代码就是react的基本写法,使用的是jsx语法,跟vue区别挺大的,推崇用js的方式去编写html和样式。

    下面简单对react组件的用法做一下演示

    我们在src目录下建立一个components文件夹

    并创建c1,c2,c3三个js文件

    我们在入口文件index.js中添加以下内容

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import C1 from './components/C1.js';
    import C2 from './components/C2.js';
    ReactDOM.render(
    	<div>
    		<C1/><App /><C2/>
    	</div>
    	, document.getElementById('root'));
    

    在c1.js文件中复制下面的代码

    import React, { Component } from 'react';
    import './C1.css';
    class C1 extends Component {
     render() {
      return (
         <div className="c1">
        c1
         </div>
         );
     }
    }
    export default C1;
    

    c2.js一样,也是添加以上代码,修改对应的名字就行。

    然后在app.js中添加如下代码

    import React, { Component } from 'react';
    import logo from './logo.svg';
    import './App.css';
    import C3 from './components/C3.js';
    
    class App extends Component {
      render() {
        return (
          <div className="App">
            <header className="App-header">
              hello
            </header>
            <C3/>
          </div>
        );
      }
    }
    
    export default App;
    

    可与看到我们在app.js中使用了c3组件,这里属于是一个嵌套组件,因为app.js也是一个组件在
    index.js中使用

    最终的效果就是c1,c2,app及app嵌套组件c3中的内容按照顺序被展示出来了

    通过以上内容,我们大致熟悉了react中组件的写法方式,接下来我们来做一个todolist小项目

    todolist项目

    image

    我们还是使用create-react-app来创建一个名为todolist-react的项目
    在src下面建立components文件夹,并添加
    appform,applist,apptabs,apptodos这四个js文件,index.js依然作为我们的项目入口文件

    添加以下几条默认数据传递到App容器组件中

    let data = [
     {id: 0, text: '吃饭唱歌打豆豆1', complete: false},
     {id: 1, text: '吃饭唱歌打豆豆2', complete: false},
     {id: 2, text: '吃饭唱歌打豆豆3', complete: true},
    ]
    
    ReactDOM.render(<App data={data}/>, document.getElementById('root'));
    

    在app.js文件中

    state = {
          choosevalue : 1,//筛选 1全部 2未完成 3已完成
          data: this.props.data
      }
    

    state作为数据管理,添加data熟悉并使用this.props.data获取到父组件data列表数据

    在render函数中通过data属性传入到applist组件中

    render() {
        const { data } = this.state; 
        return (
          <div className="App">
            <AppForm 
              AddTodoItem={this.OnAddTodoItem.bind(this)} />
    
            <AppTabs SubmitChooseValue={this.ChooseValue.bind(this)}/>
            <AppList 
              data={this.state.data}
              choosevalue={this.state.choosevalue} 
              ChangeCompleteTop={this.AllChangeComplete.bind(this)}
              DeleteItemTop={this.AllOnDeleteItem.bind(this)}/>
          </div>
        );
      }
    

    然后,在我们的applist中对data进行遍历将值赋给每一个item项,AppTodos作为嵌套组件将id, text, complete以及index值传递过去

    {this.props.data.map(({ id, text, complete }, index) => (
          		<AppTodos 
    	               key={index} 
    	               id={id} 
    	               text={text} 
    	               complete={complete}/>
            ))}
    

    appform组件用来对用户输入进行添加到待办事项中

    <form className='ui reply form'
    		onSubmit={this.handleSubmit.bind(this)}>
            <div className='field' style={styles.title}>
              <input type='text' placeholder='TODO' ref='text' />
            </div>
    
            <button type='submit' className='ui blue button'>
                添加
            </button>
          </form>
    

    当用户点击添加时候会触发onSubmit事件,通过this.refs.text.value获取到用户输入的值后调用父组件AddTodoItem函数并将新数据加入到列表中

    handleSubmit (event) {
    	    event.preventDefault()
    	    let text = this.refs.text.value
    	    
    	    if (!text.trim()) {
    	      alert("Input can't be null")
    	      return
    	    }
    	    
    	    let id = uuid();
    	    this.props.AddTodoItem({id,text,complete:false});
      }
    

    app.js文件中监听OnAddTodoItem事件

    // 合并data,并更新state
      OnAddTodoItem (newItem) {
        let newdata = this.state.data.concat(newItem);
        this.setState({data : newdata});
      }
    

    这样我们添加的数据就会直接显示在列表中了

    其他的功能,还有诸如数据过滤,全部、完成、未完成
    状态修改及删除

    由于时间关系,而且代码本身也比较简单,直接看代码也能看的懂,剩余部分功能代码我上传到github上面,可以直接fork下来阅读,或者跟着代码写一遍

    todolist-react项目地址

    react父子组件通信

    在项目中我们的app.js和appform.js。app.js作为父组件,这里涉及到父子组件通信

    1、app.js添加OnAddTodoItem函数
    用于合并data,并更新state

      OnAddTodoItem (newItem) {
        let newdata = this.state.data.concat(newItem);
        this.setState({data : newdata});
      }
    

    2、在AppForm组件标签添加AddTodoItem函数bind指向OnAddTodoItem

      <AppForm 
              AddTodoItem={this.OnAddTodoItem.bind(this)} />
    

    3、form.js子组件中通过props触发AddTodoItem函数

    this.props.AddTodoItem({id,text,complete:false});
    

    jxs语法样式对象声明

    styles样式对象声明是jxs语法中声明样式的一种方式,也可以通过className来添加样式

    var styles = {
      'title': {
         200,
        display: 'inline-block',
        marginRight: 10,
        verticalAlign: 'top'
      }
    }
    
    
    <div className='field' style={styles.title}>
              <input type='text' placeholder='TODO' ref='text' />
            </div>
    

    refs获取表单值

    使用this.refs.all.value可以直接拿到表单中的value值, 前提需要在表单中设定ref的值ref='all'

    handleAll () {
    	    let all = this.refs.all.value;
    	    this.props.SubmitChooseValue(all);
    	}
    	
    	
    	<button 
               type='submit' 
               style={styles.top} 
               className='ui blue button' 
               value='1' 
               ref='all'
               onClick={this.handleAll.bind(this)}
             > 
    

    数组遍历显示列表

    我们可以直接在return中编写遍历语句,使用{}大括号包住

    render() {
    
    	// 通过不同的choosevalue值 过滤list内容
    	var value = this.props.choosevalue;
    	// alert(value)
    
        return (
          <div>
          	{this.props.data.map(({ id, text, complete }, index) => (
          		<AppTodos 
    	               key={index} 
    	               id={id} 
    	               text={text} 
    	               complete={complete}/>
            ))}
          </div>
        )
     }
    

    除了以上这种方式,也可以这样

    在return之外进行遍历,然后返回一个参数,将返回参数添加到return中即可

    	render() {
    
    	// 通过不同的choosevalue值 过滤list内容
    	var value = this.props.choosevalue;
    	// alert(value)
    	var list = this.props.data.map(({ id, text, complete }, index) => {
    		return <AppTodos 
                   key={index} 
                   id={id} 
                   text={text} 
                   complete={complete}/>
    	})
        return (
          <div>{list}</div>
        )
    }
    

    其实jsx本身其实也是一种表达式,在编译之后,JSX 其实会被转化为普通的 JavaScript 对象。
    意味着,我们可以在 if 或者 for 语句里使用 JSX,将它赋值给变量,当作参数传入,作为返回值都可以

    function getGreeting(user) {
      if (user) {
        return <h1>Hello, {formatName(user)}!</h1>;
      }
      return <h1>Hello, Stranger.</h1>;
    }
    

    最后

    以上就是简单了解对react的使用,然后做了一个todolist小demo,涉及到了父子组件通信,因为只有2层,所以使用props完全就可以,没有任何问题,但是假如项目更加复杂,涉及组件比较多,父子组件通信,子组件与子组件通信,我们就需要引入redux来做数据的状态管理了 ,类似vue中的vuex一样。之后,进一步学习react,对react的生命周期和router路由以及redux状态管理做一个了解和学习使用

    参考阅读

    http://caibaojian.com/react/
    react新手demo——TodoList
    来自一位react新手的react入门须知
    阮一峰react教程
    React入门看这篇就够了

  • 相关阅读:
    Vim
    CMake学习之路
    linux tree命令以树形结构显示文件目录结构
    代码阅读软件Understand安装
    ROS学习之ShadowRepository
    WPF初学(一)——布局【良好界面的基础】
    浅学JSON——Json.NET之首次试手
    JSON资料汇总
    自定义视图 视图控制器(UIViewController)
    UIView Subclass(UI,UIButton,UITextField,UILabel)
  • 原文地址:https://www.cnblogs.com/fozero/p/10346117.html
Copyright © 2011-2022 走看看