美文网首页
react学习(2019/7/30-8/7)

react学习(2019/7/30-8/7)

作者: 洛音轩 | 来源:发表于2019-11-30 10:48 被阅读0次

    今日总结

    课上提到的内容

    1. 讲了react要学习的内容提纲

    • react 基础,JSX语法,插件
    • react-router 路由
    • redux 状态管理
    • ant-ui 组件库(自己学习)

    2.基础知识

    • react是什么?

        帮助构建页面的js库
      
    • 组件开发方式

      类组件:有状态(state)和完整的生命周期

      和函数式:只做展示(hook自有状态)

    作业

    1.大家根据我们今天讲到的内容,结合自己的学习,写一篇关于jsx的使用,组件相关的总结

    • JSX是JavaScript的语法扩展,具有JavaScript的全部功能
        const element = <h1>Hello, world!</h1>;
    
    • 为什么使用JSX?
      • React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合
      • React 并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离
    • 在JSX中嵌入表达式
        const name = 'Josh Perez';
        const element = <h1>Hello, {name}</h1>;
        ReactDOM.render(
        element,
        document.getElementById('root')
        );
    //在JSX语法中,你可以在大括号内放置任何有效的 JavaScript 表达式。例如,2 + 2,user.firstName或 formatName(user)都是有效的JavaScript表达式
    
      • 为了便于阅读,我们会将 JSX 拆分为多行
    • JSX 也是一个表达式
      • 你可以在 if 语句和 for 循环的代码块中使用 JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回 JSX
    • JSX 特定属性
      • 你可以通过使用引号,来将属性值指定为字符串字面量,也可以使用大括号,来在属性值中插入一个 JavaScript 表达式
        const element = <div tabIndex="0"></div>;
    
        const element = <img src={user.avatarUrl}></img>;
    
    • 使用 JSX 指定子元素
      • 假如一个标签里面没有内容,你可以使用 /> 来闭合标签,就像 XML 语法一样:
        const element = <img src={user.avatarUrl} />;
      • JSX 标签里能够包含很多子元素:
    • JSX 防止注入攻击
    • JSX 表示对象
      • Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用,以下两种示例代码完全等效:
        const element = (
        <h1 className="greeting">
            Hello, world!
        </h1>   
        );
        const element = React.createElement(
        'h1',
        {className: 'greeting'},
        'Hello, world!'
        );
    
    • react生命周期
      组件传给ReactDom.render()->调用组件的构造函数->this.state初始化->React调用组件的render()方法->组件插入DOM中后调用ComponentDidMount()->当组件被移除的时候,React 就会调用 componentWillUnmount()
    • 正确使用State
    1. 不要直接修改State,而是应该使用setState,构造函数是唯一可以给this.state赋值的地方

    2. State的更新可能是异步的,出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。

    • 因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
    • 例如,此代码可能会无法更新计数器:
      // Wrong
      this.setState({
      counter: this.state.counter + this.props.increment,
      });
      
    • 要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
      // Correct
      this.setState((state, props) => ({
      counter: state.counter + props.increment
      }));
      
    1. State 的更新会被合并

    2.在201907-B-Train项目,自己的目录下,用create-react-app创建一个项目,项目名称叫做react-demo

    3.可以使用这个 codesandbox.io去做一些在线开发验证

    4.React.Children(demo5)

    • React.Children 提供了用于处理 this.props.children 不透明数据结构的实用方法
    • this.props.children有三种可能性。如果组件没有子节点,则值为undefined; 如果单个子节点,一个对象; 如果有多个子节点,则为数组

    5.PropTypes属性(demo6)

    • 定义title应该是个字符串
        class MyTitle extends React.Component {
            static propTypes = {
                title: PropTypes.string.isRequired,
            }
            render() {
                return <h1> {this.props.title} </h1>;
            }
            static defaultProps = {//给title设置默认值
                title: 'Hello World',
            }
        }
    

    6.React.createRef,ref(demo7)

    • 有时您需要引用组件中的DOM节点。React为您提供了ref将DOM节点附加到由其创建的实例的属性React.createRef()
        class MyComponent extends React.Component {
            constructor(props) {
              super(props);
              this.myTextInput = React.createRef();
              this.handleClick = this.handleClick.bind(this)
            }
            handleClick() {
              this.myTextInput.current.focus();
            }
            render() {
              return (
                <div>
                  <input type="text" ref={this.myTextInput} />
                  <input type="button" value="Focus the text input" onClick={this.handleClick} />
                </div>
              );
            }
          }
    
          ReactDOM.render(
            <MyComponent />,
            document.getElementById('example')
          );
        }
    

    7.this.state(demo8)

    • React将组件视为状态机,并用于this.state保存组件的状态,this.setState()以更新this.state和重新呈现组件

    8.react生命周期

    • componentWillMount():在初始渲染发生之前触发一次。连接消息监听器的好地方。this.setState在这里不起作用。
    • componentDidMount():在初始渲染发生后触发一次。可以用this.getDOMNode()。
    • componentWillUpdate(object nextProps,object nextState):在组件对DOM进行更新后触发。可以this.getDOMNode()用于更新。
    • componentDidUpdate(object prevProps,object prevState):在将组件的更新刷新到DOM之后立即调用。初始渲染不会调用此方法。将此作为在更新组件时对DOM进行操作的机会。
    • componentWillUnmount():在从DOM卸载组件之前立即触发。删除消息监听器或一般清理的好地方。
    • componentWillReceiveProps(object nextProps):在组件接收新props时触发。你可能想要this.setState依赖props。
    • shouldComponentUpdate(object nextProps,object nextState):在收到新的props或state时呈现之前触发。return false如果你知道不需要更新。

    今天做了什么

    1.写了日志

    2.按照官网写了井字棋的小游戏

    3.学习理解了阮一峰react的11个demo

    4.官网看到了核心概念的第7条条件渲染

    今日心得

    今天通过老师讲解大致react学习的大纲,通过react官网逐步去适应了react的JSX编写规则,通过实践井字棋游戏,也理解了react父子组件的传参,只能通过props传参,state 和 props 之间最重要的区别是:props 由父组件传入,而 state 由组件本身管理。组件不能修改 props,但它可以修改state,state只能通过setState来修改等基础知识。
    

    做了什么

    • 主要课上学习了react的条件渲染、列表渲染、表单、ref、状态提升等。
    • 做了todo-list demo,实现了react的组件嵌套,父子组件的传值,顶层组件数据控制,状态管理等

    有什么收获

    • 写demo的时候遇到了很多问题,比如我想通过子组件去处理父组件传过来的props但是,在子组件中处理父组件的数据,逻辑非常混论,并且状态更新难以管理,后来,直接在父组件上面进行数据的绑定,函数的分装,然后通过事件传递给子组件,然后执行,完成状态管理
    • 在处理事件的时候,遇到了事件this绑定的问题,有三种方法可以实现,constuctor中事件.bind(this)、箭头函数和传递的时候.bind(this)
    • 还遇到了元事件e的隐式和显示传递问题,()=>{this.handle(item)}不传递e,(e)=>{this.handle(e)}
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    
    // 类组件
    // class Square extends React.Component{
    //     render(){
    //         return (
    //             <button 
    //             className="square" 
    //             onClick={()=>{this.props.onClick()}}
    //             >
    //                 {this.props.value}
    //             </button>
    //         );
    //     }
    // }
    // 等价于函数组件
    function Square(props){
        console.log(props)
        return (
            <button 
            className="square" 
            onClick={props.onClick}
            // onClick={props.onCd}
            >
                {props.value}
            </button>
        );
    }
    
    function calculateWinner(squares) {
        const lines = [
          [0, 1, 2],//[x,o,x,o,x,o,null,x,null,null]
          [3, 4, 5],
          [6, 7, 8],
          [0, 3, 6],
          [1, 4, 7],
          [2, 5, 8],
          [0, 4, 8],
          [2, 4, 6],
        ];
        for (let i = 0; i < lines.length; i++) {
          const [a, b, c] = lines[i];
          if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
            return squares[a];
          }
        }
        return null;
      }
    
    class Board extends React.Component{
        // constructor(props){
        //     super(props);  
        //     this.state = {
        //         squares:Array(9).fill(null),
        //         xIsNext:true,
        //     }                                                                 
        // }
        // handleClick=(i)=>{
        //     const squares = this.state.squares.slice();
        //     if (calculateWinner(squares) || squares[i]) {
        //         return;
        //     }
        //     squares[i]= this.state.xIsNext ? 'X' : 'O';
        //     this.setState({
        //         squares:squares,
        //         xIsNext:!this.state.xIsNext,
        //     });
        // }
        renderSquire(i){
            console.log(this.props);
            return (
            <Square 
                // value={this.state.squares[i]}
                // onClick={()=>this.handleClick(i)}
                value={this.props.squares[i]}
                onClick={()=>this.props.onClick(i)}
                // onClick={()=>this.props.onCd()}
            />);
        }
        render(){
            // const winner = calculateWinner(this.state.squares);
            // let status;
            // if(winner){
            //     status="Winner:"+winner;
            // }else{
            //     status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
            // }
            // const status = 'Next player:'+ (this.state.xIsNext ? 'X' : 'O');
            return (
                <div>
                    {/* <div className="status">{status}</div> */}
                    <div className="board-row">
                        {this.renderSquire(0)}
                        {this.renderSquire(1)}
                        {this.renderSquire(2)}
                    </div>
                    <div className="board-row">
                        {this.renderSquire(3)}
                        {this.renderSquire(4)}
                        {this.renderSquire(5)}
                    </div>
                    <div className="board-row">
                        {this.renderSquire(6)}
                        {this.renderSquire(7)}
                        {this.renderSquire(8)}
                    </div>
                </div>
            );
        }
    }
     
    class Game extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
              history: [{
                squares: Array(9).fill(null),
              }],
              stepNumber:0,
              xIsNext: true,
    
            };
            console.log(props)
        }
    
        handleClick(i){
            // const history = this.state.history;
            const history = this.state.history.slice(0, this.state.stepNumber + 1);
            const current = history[history.length - 1];
            const squares = current.squares.slice();
            // const squares = this.state.squares.slice();
            if (calculateWinner(squares) || squares[i]) {
                return;
            }
            squares[i]= this.state.xIsNext ? 'X' : 'O';
            this.setState({
                history: history.concat([{
                    squares: squares,
                }]),
                stepNumber:history.length,
                xIsNext:!this.state.xIsNext,
            });
        }
        jumpTo(step){
            this.setState({
                stepNumber:step,
                xIsNext:(step % 2)===0,
            })
        }
        render() {
            const history = this.state.history;
            const current = history[this.state.stepNumber];
            const winner = calculateWinner(current.squares);
            const moves = history.map((step, move) => {
                const desc = move ?
                  'Go to move #' + move :
                  'Go to game start';
                return (
                  <li key={move}>
                    <button onClick={() => this.jumpTo(move)}>{desc}</button>
                  </li>
                );
              });
    
            let status;
            if(winner){
                status="Winner: "+winner;
            }else{
                status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
            }
            return (
            <div className="game">
                <div className="game-board">
                <Board 
                squares={current.squares}
                onClick={i =>this.handleClick(i)}
                // onCd={()=>this.l(1)}
                />
                </div>
                <div className="game-info">
                <div>{status}</div>
                <ol>{moves}</ol>
                </div>
            </div>
            );
        }
    }
      // ========================================
    ReactDOM.render(
    <Game />,
    document.getElementById('root')
    );
    

    学习内容

    1. react-router学习

    2. router配置

    3. 路由匹配原理

    4. 默认路由

    练习内容

    完成路由切换的demo

    遇到的问题?

    未完成用a标签实现路由跳转

    代码:

    import React from 'react';
    import { BrowserRouter as Router, Route, Link } from "react-router-dom";
    import Introduction from './Introduction'
    import Introduction1 from './Introduction1'
    import Basis from './Basis'
    import './App.css'
    function App(){
        return (
            <Router>
                <div className="app">
                    <ul className="menu">
                        <li>
                            <Link activeClassName="active" to="/">Introduction</Link>
                        </li>
                        <li>
                            <Link activeClassName="active" to="/Introduction1">1.简介</Link>
                        </li>
                        <li>
                            <Link to="/basis">2.基础</Link>
                            <ul>
                                <li>
                                    <Link>2.1路由配置</Link>
                                </li>
                                <li>
                                    <Link>2.2路由匹配原理</Link>
                                </li>
                                <li>
                                    <Link>2.3History</Link>
                                </li>
                                <li>
                                    <Link>2.4默认路由</Link>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <Link to="/">3.高级用法</Link>
                            <ul>
                                <li>
                                    <Link>2.1路由配置</Link>
                                </li>
                                <li>
                                    <Link>2.2路由匹配原理</Link>
                                </li>
                                <li>
                                    <Link>2.3History</Link>
                                </li>
                                <li>
                                    <Link>2.4默认路由</Link>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <Link to="/">4.升级指南</Link>
                        </li>
                        <li>
                            <Link to="/">5.排错</Link>
                        </li>
                        <li>
                            <Link to="/">6.Api文档</Link>
                        </li>
                        <li>
                            <Link to="/">7.词汇表</Link>
                        </li>
                        
                    </ul>
                    <div className="content">
                        <Route exact path="/" component={Introduction} />
                        <Route exact path="/Introduction1" component={Introduction1} />
                        <Route exact path="/Basis" component={Basis} />
                    </div>
                </div>
            </Router>
        )
    }
    export default App
    

    学习内容

    redux基础学习

    Action,Reducer,Store,数据流的学习

    1. action 只是一个带有type属性的普通对象
    2. store 是一个用于改变state状态的对象
     storeChange(){
         this.setState(store.getState())
     }
     store.subscribe(this.storeChange) //订阅Redux的状态
     store.dispatch(action)//触发一次订阅
    
    1. reducer是一个纯函数,接受上一个state和action作为参数,并返回下一个要更新的state给store,reducer里面的内容主要是通过action的type去对下一个state进行限定和修改,但是不更新

    今日总结

    1. 今天做了什么

    1. 今天主要做了表单的页面部分内容
    2. 是通过使用antd插件进行构建的

    2. 学习

    1. 学习了antd的一些基本使用方法
    安装,引入,按模块导入,导入css文件
    

    3. 收获

    1. 最后引入的样式很完美,但是因为对这个库根本不熟悉所以,中间的数据不知道怎么传递,最后以失败告终,从而自己的进度就拉下了,
    2. 感悟和收获:以后做项目,一定先写逻辑再写页面样式,这样做有很多好处,交互的逻辑先写完,样式可以慢慢加,但写样式,如果逻辑加不进去可能导致重写。

    明日计划

    继续redux学习


    image.png
    image.png

    今日总结

    1.做了什么?

    1. 重写了项目的交互逻辑
    2. 重写了项目的页面
    3. 明白了redux的数据状态管理:component创建action,通过store.dispatch(action)传递给store,store接受到action后先不处理,而是将action当参数传递给reducer,reducer根据传来的action,将state做相应的更新以后,将新的state返还给store,store接受到新的state后更新全局的state,store可以通过store.subscribe订阅store的改变

    2.学了什么

    1. 上面描述的redux的工作机制
    2. 对selet和form等使用和学习

    3.明日计划

    继续完善项目的校验功能
    

    今日总结

    1.做了什么?

    1. 用mockjs模拟了后台数据,并且通过axios能获取到,通过里面的参数也可以向后台传递参数
    import Mock from 'mockjs'//导入mockjs模块
    
    Mock.mock('/data','get',(options)=>{//options 为axios传递给mock的数据,return的对象为mock给axios的body内数据内容
        console.log(options);
        return{    
            'list|1':[{
                'id|+1': 1,
                'selectValue':null,
                'educationValue':null,
                'startTime':null,
                'endTime':null,
                'firstMajor':null,
                'firstMajorGPA':null,
                'secondMajor':null,
                'secondMajorGPA':null
            }]
        }
    })
    
    1. 通过for...of加switch做提交前的校验
            for(let i of list) {
                for(let item of Object.entries(i)){
                    let [key,value] = item;
                    console.log(key);
                    switch (key){
                        case "id": 
                            value===null?alert("id未填写"):console.log(value);
                            break
                        case "selectValue":
                            value === null ? alert("学校未填写") : console.log(value);
                            break
                        case "educationValue":
                            value === null ? alert("学历未填写") : console.log(value);
                            break
                        case "startTime":
                            value === null ? alert("起始时间未填写") : console.log(value);
                            break
                        case "endTime" :
                            value === null ? alert("终止时间未填写") : console.log(value);
                            break
                        case "firstMajor":
                            value === null ? alert("第一学位未填写") : console.log(value);
                            break
                        case "firstMajorGPA":
                            value === null ? alert("第一学位GPA未填写") : console.log(value);
                            break
                        case "secondMajor":
                            value === null ? alert("第二学位未填写") : console.log(value);
                            break
                        case "secondMajorGPA":
                            value === null ? alert("第二学位GPA未填写") : console.log(value);
                            break
                        default:
                            console.log("success");
                    }
                }
            }
    

    2.学了什么

    1. mockjs和axios的简单使用
    2. switch的使用
    3. for...of的使用

    3.明日计划

    继续完善表单的前台,后端校验和提交前的校验等功能,将代码分块
    

    今日总结

    1.做了什么?

    1. 继续完善表单
      • 将代码分块,将所有的action操作全部提取出来,放在actionTypes.js里面,将action提取出来放在actionCreators.js
      • 对表单的数据和UI做了双向绑定
    2. 复习了Generator函数,看来一部分redux-saga内容

    2.遇到问题

    1. 几个需要注意的地方
      • 刚开始的input监控事件是用onBlur事件,但是这个不能用于数据的双向绑定,因为它不能实时更新input框里面的内容,所以会造成input框数据第一次可以输入,但是第二次输入不了的情况,因为第一次的值绑定了以后,输入框再要改变必须要onBlur才行,而输入内容的时候是onFocus
      • 初始化数据,包括后面新增数据项的初始化数据尽量不要设置成null,而是缓存空字符串,要不然会有警告

    3.明日计划

    • 继续学习redux-saga内容

    今日总结

    做了什么

    1. 对redux-saga基础进行学习
    2. 对angular1.x进行学习,学习了指令,表达式,模型,$scope,控制器和过滤器等

    遇到什么问题

    1. redux-saga文档给的例子,只有分支上的可以跑起来,master分支上的会报错
    2. angular1.x没有官方文档,只能通过菜鸟教程去学习,上面给的例子很简单,导致复杂应用的开发的话没什么借鉴意义

    有哪些收获

    • redux-saga还很迷,后面还需要好好重新学习,感受了老框架angular初代版本的魅力,觉得学习和使用的成本很低,还挺实用的

    明日计划

    • 开始hzero前端开发的学习

    相关文章

      网友评论

          本文标题:react学习(2019/7/30-8/7)

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