美文网首页React
React 总结 - 基础篇

React 总结 - 基础篇

作者: zz77zz | 来源:发表于2019-06-24 16:38 被阅读0次

    React编写简书项目

    这是看慕课网上的React课程做的总结笔记

    MDN上的js教程 基础需打牢
    重新介绍 JavaScript(JS 教程)

    环境搭建

    
    npm install -g create-react-app
    create-react-app my-app
    
    cd my-app
    npm start
    

    项目如果安装失败 具体请bing或者谷歌 又或者网络问题 可以设置npm淘宝源

    npm config set registry https://registry.npm.taobao.org
    -- 配置后可通过下面方式来验证是否成功
    npm config get registry
    
    项目运行成功
    • 项目目录
      项目目录

    有两个文件要特殊提一下

    • serviceWorker 断网后还可以访问
    • index.js 入口文件
    • public/manifest.json 这是个PWA应用 当成一个应用来使用 快捷方式在桌面上
    • 把不需要的文件删除

    编写Todolist

    需提前了解

    • styl语法
    • 函数式编程
    • ES6 箭头函数 结构赋值 类
    • all in js jsx 语法糖
    vscode 安装jsx 语法糖插件

    创建todolist.js 组件
    index.js 入口文件引入 todolist组件

    todolist组件代码

    import React, { Component, Fragment } from 'react';
    import './style.css';
    
    class Todolist extends Component {
      constructor(props) {
        super(props);
        this.state = {
          inputValue: '',
          list: ['学英语', '写代码', '把妹']
        }
      }
    
      render() {
        return (
          <Fragment>
    
            <div>
              <label htmlFor="insert" style={{marginRight:20+'px'}}>输入内容</label>
              <input id="insert" className="input" placeholder="请输入今日待办事项" value={this.state.inputValue} onChange={this.handleChange.bind(this)} />
              <button onClick={this.handleClick.bind(this)}>submit</button>
            </div>
                {/*
                    如果需要在jsx里设置转义过后的 比如h1 标签 h2标签 span标签内容  就用到dangerouslySetInnerHTML
                    <ul>
                      {
                        this.state.list.map((item,index) =>{
                          return <li key={index} onClick={this.handleDelete.bind(this,index)} dangerouslySetInnerHTML={{__html: item}}></li>
                        })
                      }
                    </ul>
                  */}
            <ul>
              {
                this.state.list.map((item, index) => {
                  return <li key={index} onClick={this.handleDelete.bind(this, index)}>{item}</li>
                })
              }
            </ul>
    
          </Fragment>
        )
      }
    
    
      handleChange(e) {
        this.setState({
          inputValue: e.target.value
        })
      }
    
      handleClick(e) {
        this.setState({
          list: [...this.state.list, this.state.inputValue],
          inputValue: ''
        })
      }
    
      handleDelete(index) {
        const _list = [...this.state.list]
        console.log(index)
        _list.splice(index, 1)
        this.setState({
          list: _list
        })
      }
    }
    
    export default Todolist;
    
    
    

    创建style.css 并引入

    注意以下几个问题

    • JSX语法
      • 内联样式的写法
      • jsx注释
      • lable的for属性要写成htmlFor 不然会认为是for循环
    • 注意constructor 要super(props) 然后声明状态
    • 不能直接操作state Immutable.js

    组件拆分 组件传值

    这章是重点

    把Todolist里的每个事项拆分成子组件 方法如下

    • 创建todolist-item组件
    • 引入todolist-item
    • 代码如下:
      
      // todolist 父组件代码 调用部分
      <Todoitem index={index} 
                content={item}
                deleteitem={this.handleDelete.bind(this)}
      />
      
      //todolist-item 组件代码
      import React, { Component } from 'react';
      
      class Todoitem extends Component {
      
          constructor(props){
              super(props)
              this.handleDelete = this.handleDelete.bind(this)
          }
      
          render() {
              return (
                  <div onClick={this.handleDelete}>
                      {this.props.content}
                  </div>
              );
          }
      
          handleDelete(){
              console.log(this.props.index)
              this.props.deleteitem(this.props.index)
          }
      }
      
      export default Todoitem
      
    • 注意以下几点
      • 传值 父组件定义属性 子组件接受props 包括数据 方法等等都可以
      • 尤其注意 this 因为绑定不正确会报没有找到某一个属性或者其他错误
      • 子组件要调用父组件的方法 并改变父组件的数据 就用属性将方法传递过去 子组件props接受方法即可

    父组件代码优化

    import React, { Component, Fragment } from 'react';
    import Todoitem from './todolist-Item';
    import './style.css';
    
    class Todolist extends Component {
      constructor(props) {
        super(props);
        this.state = {
          inputValue: '',
          list: ['学英语', '写代码', '把妹']
        }
    
        // 页面一开始就绑定好方法this指向
        this.handleClick= this.handleClick.bind(this)
        this.handleDelete = this.handleDelete.bind(this)
        this.handleChange = this.handleChange.bind(this)
      }
    
      render() {
        return (
          <Fragment>
            <div>
              <label htmlFor="insert" style={{marginRight:20+'px'}}>输入内容</label>
              <input 
                id="insert" 
                className="input" 
                placeholder="请输入今日待办事项" 
                value={this.state.inputValue} 
                onChange={this.handleChange} 
              />
              <button onClick={this.handleClick}>submit</button>
            </div>
            
            <ul>{this.getTodoItem()}</ul>
          </Fragment>
        )
      }
    
      getTodoItem(){
        return  this.state.list.map((item, index) => {
            return ( 
                <Todoitem 
                  key={index}
                  index={index} 
                  content={item}
                  deleteitem={this.handleDelete}
                />
            )
          })
      }
    
      handleChange(e) {
        const value = e.target.value
        //setState 可以写方法 并且返回一个对象  对象变成函数 最外侧把要更改的值 保存一下
        this.setState( 
          ()=> ({inputValue : value}) 
        )
        // this.setState({
        //   inputValue: e.target.value
        // })
      }
    
      handleClick(e) {
        this.setState((prevState)=>({
            list: [...prevState.list, prevState.inputValue],
            inputValue: ''
          })
        )
      }
    
      handleDelete(index) {
        // const _list = [...this.state.list]
    
        // console.log(index)
        // _list.splice(index, 1)
        // this.setState({
        //   list: _list
        // })
        this.setState(
          
          (prevState)=>{
            console.log(prevState)
            const _list = [...prevState.list]
            _list.splice(index, 1)
            return { list : _list }
          }
        )
      }
    }
    
    export default Todolist;
    
    

    子组件代码优化

    import React, { Component } from 'react';
    
    class Todoitem extends Component {
    
        constructor(props){
            super(props)
            this.handleDelete = this.handleDelete.bind(this)
        }
    
        render() {
            const { content } = this.props
            return (
                <div onClick={this.handleDelete}>
                    {content}
                </div>
            );
        }
    
        handleDelete(){
            console.log(this.props.index)
            const { deleteitem,index } = this.props
            deleteitem(index)
        }
    }
    
    export default Todoitem
    
    

    引发一些思考

    我觉得这是听到最舒服的部分 带进自己的思考 才理解了React出现的原因 之前在学习vue的过程中并没有感受到 估计是之前比较木讷

    • 声明式开发: 面向数据编程 类似于盖房之前把设计稿图纸画好 React会自动开始建造

    • 与其他框架共同开发: 在我理解看来 比如项目中操作交互比较复杂的情况下可以用React来实现 页面其他部分保持不变就可以了
      类似 购物车可以写成一个组件 页面其他部分继续用Jq来操作编写页面 等等

    • 组件开发 首字母大写

    • 父子组件传值 F:父组件 Z:子组件
      F=>Z : F定义属性 Z用props接受
      Z=>F : Z用F定义的方法 F把该方法传递给Z Z组件调用方法 间接操作F值 实现Z=>F 传值

    • 单项数据流 Z可以使用F传来的值 但不能修改这个值 之所以单向我想了下 如果子组件特别多项目大 Z更改数据 会导致 其他组件接受到的数据也被更改 破坏了数据源

    • React视图层框架 它只负责数据渲染工作 不然也不会出现Redux Flux 这种做数据层框架做数据传递 处理

      A->B做数据传递
    • 函数式编程 非常容易做自动化测试等等

    相关文章

      网友评论

        本文标题:React 总结 - 基础篇

        本文链接:https://www.haomeiwen.com/subject/nbuoqctx.html