美文网首页
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