react核心

29.9React课程

第1节:react核心

(react核心&)

react核心&

如果是cdn最好增加crossorgin跨域属性,直接避开校验直接引入资源文件

crossorigin跨域引入CDN,create-react-app,npm run eject

快速搭建react脚手架

构建npm run build 生产构建,CIA工具配置通过eject打碎项目可以看到webpack的配置,执行就不可逆。

 

(初识Jsx&)

初识Jsx&

jsx语法,{}

函数也是表达式

把变量与函数可以直接插入jsx语法中,react.render进行数据渲染

把jsx挂在到root 的html中

(条件渲染&)

条件渲染&

要在jsx以外做判断

逻辑与&&,条件语句不能再表达式里使用

列表渲染

具有唯一标识性的做为key

显示图片

不能使用相对路径./logo.png,打包路径不同

动态渲染日期Date(),jsx的条件渲染表达式,arr,map,src与style样式图片引入,className,css模块化

import React from "react"; //=>vdom
import ReactDOM from "react-dom";
import pic from "./logo.png";
import classNames from "classnames";
import TestClass from "./TestClass";
import TestHandle from "./TestHandle";
//引入css模块
import "./index.css";

//引入模块化css 需要名称

import StyleCss from "./index.module.css";
//jsx

//使用表达式 {} 里面 只要是合法的表达式 都可以
// const name = "react";
// const user = {
//   firtName: "han",
//   lastName: "lao"
// };

// function joinName(user) {
//   return user.firtName + "-" + user.lastName;
// }

// const tags = <span>hello span</span>;

// const jsx = <p>我喜欢{tags}</p>; //原生dom元素 =》React 元素

// React.createElement(<p>我是p标签</p>)

//动态渲染
// function tick() {
//   const ele = <div>{new Date().toLocaleTimeString()}</div>;
//
// }

// tick();

// setInterval(tick, 1000);
const isShow = true;
// let jsx;
// if (isShow) {
//   jsx = <p>我喜欢1</p>;
// } else {
//   jsx = <p>我喜欢2</p>;
// }

//条件语句 不能在{}里使用
// if
// 三元运算
// 逻辑与
const jsx = isShow && <p>我喜欢1</p>;

const arr = [1, 2, 3, 4];

const lis = arr.map((item, index) => <li key={index}>{item}</li>);

// ReactDOM.render(<ul>{lis}</ul>, document.getElementById("root"));

//css-in-js
// const styles = {
//   border: "1px red solid",
//   height: 200
// };

//为什么要使用className,目的是避开关键字

//  /* <label htmlfor=""></label> */

// function Lis(props){

// }

//首字母必须要大写
function Welcome(props) {
  console.log(props);
  //遵守单向数据流原则,不要对props进行修改
  //   return [<div>我是div1</div>, <div>我是div2</div>];
  //   解决列表渲染
  return (
    // <React.Fragment>
    //   <div>1</div>
    //   <div>2</div>
    // </React.Fragment>
    <ul>{lis}</ul>
  );
}
//使用数组

//dom元素属性
{
  /* <img
    src={pic}
    alt="图片"
    className={classNames("border1", { height2: true })}
/> */
}
ReactDOM.render(
  <TestHandle name={"React Comp"} />,
  document.getElementById("root")
);

index.css

.border1 {
  border: 1px blue solid;
}

.height2 {
  height: 200px;
}

设置元素样式,替换内部元素样式

引入css样式

定义样式,className引入外面class模块类名

.border1 {
  border: 1px blue solid;
}

.height2 {
  height: 200px;
}

模块化的css

index.module.css

.border1 {
  border: 1px blue solid;
}

.height2 {
  height: 200px;
}

样式解决方案 styled-components,styled-jsx,classnames

(组件&)

组件&

函数式组件与类组件

函数组件与props

import React from "react"; //=>vdom
import ReactDOM from "react-dom";
import pic from "./logo.png";
import classNames from "classnames";
import TestClass from "./TestClass";
import TestHandle from "./TestHandle";
//引入css模块
import "./index.css";

//引入模块化css 需要名称

import StyleCss from "./index.module.css";
//jsx

//使用表达式 {} 里面 只要是合法的表达式 都可以
// const name = "react";
// const user = {
//   firtName: "han",
//   lastName: "lao"
// };

// function joinName(user) {
//   return user.firtName + "-" + user.lastName;
// }

// const tags = <span>hello span</span>;

// const jsx = <p>我喜欢{tags}</p>; //原生dom元素 =》React 元素

// React.createElement(<p>我是p标签</p>)

//动态渲染
// function tick() {
//   const ele = <div>{new Date().toLocaleTimeString()}</div>;
//
// }

// tick();

// setInterval(tick, 1000);
const isShow = true;
// let jsx;
// if (isShow) {
//   jsx = <p>我喜欢1</p>;
// } else {
//   jsx = <p>我喜欢2</p>;
// }

//条件语句 不能在{}里使用
// if
// 三元运算
// 逻辑与
const jsx = isShow && <p>我喜欢1</p>;

const arr = [1, 2, 3, 4];

const lis = arr.map((item, index) => <li key={index}>{item}</li>);

// ReactDOM.render(<ul>{lis}</ul>, document.getElementById("root"));

//css-in-js
// const styles = {
//   border: "1px red solid",
//   height: 200
// };

//为什么要使用className,目的是避开关键字

//  /* <label htmlfor=""></label> */

// function Lis(props){

// }

//首字母必须要大写
function Welcome(props) {
  console.log(props);
  //遵守单向数据流原则,不要对props进行修改
  //   return [<div>我是div1</div>, <div>我是div2</div>];
  //   解决列表渲染
  return (
    // <React.Fragment>
    //   <div>1</div>
    //   <div>2</div>
    // </React.Fragment>
    <ul>{lis}</ul>
  );
}
//使用数组

//dom元素属性
{
  /* <img
    src={pic}
    alt="图片"
    className={classNames("border1", { height2: true })}
/> */
}
ReactDOM.render(
  <TestHandle name={"React Comp"} />,
  document.getElementById("root")
);

TestClass.js 类组件,constructor ,componentDidMount,setState异步

import React, { Component } from "react";

class TestClass extends Component {
  constructor(props) {
    super(); //disbled
    // this.state = {
    //   date: new Date()
    // };

    this.state = {
      counter: 0
    };

    // this.state.counter = 1;
    //setState()
  }
  //   state = {
  //       date: new Date()
  //     };
  //生命周期函数 已挂载
  componentDidMount() {
    // this.timerId = setInterval(() => {
    //   this.setState({
    //     date: new Date()
    //   });
    // }, 1000);
    // this.setState({
    //   counter: this.state.counter + 1
    // });
    // this.setState({
    //   counter: this.state.counter + 1
    // });
    // this.setState({
    //   counter: this.state.counter + 1
    // });
    //完全取决于是否需要最新的值
    this.setState((state, props) => ({ counter: state.counter + 1 }));
    this.setState((state, props) => ({ counter: state.counter + 1 }));
    this.setState((state, props) => ({ counter: state.counter + 1 }));

    // setTimeout(() => {
    //   console.log(this.state.counter);
    // }, 0);
    document.body.addEventListener("click", this.changeValue, false);

    // console.log(this.state.counter); //1 ==== 0
  }
  componentWillUnmount() {
    // clearInterval(this.timerId);
  }
  changeValue = () => {
    this.setState({ counter: this.state.counter + 1 });
    console.log(this.state.counter);
  };
  render() {
    // return <div>{this.state.date.toLocaleTimeString()}</div>;
    return <div>{this.state.counter}</div>; //3
  }
}

export default TestClass;

s

props在的调用得到时候传入,接收父组件传递的属性并展示,props名字可以修改作为形参。

组件首字母必须要大写,大写当做组件处理,小写当做原生Dom来处理。

可以传递字符串与{}形式的 字符串,也可以传递数组和对象,所有属性函数式组件都是通过props接收的

遵守单向数据流,接收到属性不建议对属性进行修改


组件的使用呢当做一个标签来使用,首字母要大写区分原生Dom

渲染过程

return的元素只能有一个根节点,需要一个包裹元素<div>

返回兄弟级的div元素

Fragment包裹兄弟元素,可以使用短标签

使用Fragment需要有key

class组件,拥有状态与生命周期,继承component

导出直接引入组件名即可

return直接返回null不会进行任何渲染

(组件状态管理&)

组件状态管理&

数据发生变化影响页面内容,需要维护state,props在父组件指定一经指定不再改变,遵守单一数据流。

状态改变,组件重新调用render方法,更新UI。

constructor接收属性

可变的属性通过state来管理状态,不要对state直接修改,通过setState来设置

生命周期钩子,componentDidMount 当Dom已经挂在到HTML里面,钩子会自动执行,在钩子函数中增加定时器修改state来重新执行渲染render函数。

通过key来重新设置state

组件销毁的时候还要清除定时器

在类组件可以省略constructor,state通过成员变量来定义,this指向组件实例

最终输出0因为setState是异步的

state的更新会被合并,组件多次state同一个可以最终合并为一个,只有最后一个执行了,输出1

拿到最新的值,需要接受一个函数实现

获取最新state值三种方式

异步变为同步,最终结果为3

获取最新值,定时器0立即执行为3,使用原生世界

箭头函数修改this指向,setState修改state

TestClass.js

import React, { Component } from "react";

class TestClass extends Component {
  constructor(props) {
    super(); //disbled
    // this.state = {
    //   date: new Date()
    // };

    this.state = {
      counter: 0
    };

    // this.state.counter = 1;
    //setState()
  }
  //   state = {
  //       date: new Date()
  //     };
  //生命周期函数 已挂载
  componentDidMount() {
    // this.timerId = setInterval(() => {
    //   this.setState({
    //     date: new Date()
    //   });
    // }, 1000);
    // this.setState({
    //   counter: this.state.counter + 1
    // });
    // this.setState({
    //   counter: this.state.counter + 1
    // });
    // this.setState({
    //   counter: this.state.counter + 1
    // });
    //完全取决于是否需要最新的值
    this.setState((state, props) => ({ counter: state.counter + 1 }));
    this.setState((state, props) => ({ counter: state.counter + 1 }));
    this.setState((state, props) => ({ counter: state.counter + 1 }));

    // setTimeout(() => {
    //   console.log(this.state.counter);
    // }, 0);
    document.body.addEventListener("click", this.changeValue, false);

    // console.log(this.state.counter); //1 ==== 0
  }
  componentWillUnmount() {
    // clearInterval(this.timerId);
  }
  changeValue = () => {
    this.setState({ counter: this.state.counter + 1 });
    console.log(this.state.counter);
  };
  render() {
    // return <div>{this.state.date.toLocaleTimeString()}</div>;
    return <div>{this.state.counter}</div>; //3
  }
}

export default TestClass;

(事件处理&)

事件处理&

事件注意this指向问题

根据用户输入的值来展示最新的值,要更新name,获取用户输入的值,找不到this与e

箭头函数传递this,箭头函数中传递参数

通过handler绑定this,直接调用箭头函数就可以

通过bind绑定this

官方建议在构造函数中bind(this)

(组件通信&)

组件通信&

单向数据流,在子组件的事件中传入值,父组件就能接收到值了。

子组件修改父组件里面的东西。

this.props.change接收父组件传递而来的事件

解决this出现问题,传递test执行当前组件的handler函数

this传递出现异常,通过箭头函数传递

点击没有执行事件

点击div执行handle事件

传递的是test要执行test不能执行handle

处理handle()方法this的指向,子组件更改父组件属性,用到事件就要考虑this指向问题

onChange事件,onClick事件,绑定this的三种方式,状态提升

import React from "react";
class TestHandle extends React.Component {
  constructor(props) {
    super();
    this.state = {
      name: "",
      counter: 0,
      age: 18
    };
    // this.handleTest = this.handleTest.bind(this,e);
  }
  handleTest = () => {
    //如何在函数内部正确使用this
    this.setState({
      age: this.state.age + 1
    });
  };
  //   handleTest2() {
  //     //如何在函数内部正确使用this
  //     this.setState({
  //       age: this.state.age + 1
  //     });
  //   }
  //   handleTest3() {
  //     //如何在函数内部正确使用this
  //     this.setState({
  //       age: this.state.age + 1
  //     });
  //   }

  handleChange(e) {
    this.setState({
      name: e.target.value
    });
  }
  handle() {
    this.setState({
      counter: this.state.counter + 1
    });
  }
  render() {
    //bind
    //箭头函数
    return (
      <div
        onClick={e => {
          this.handleTest(e);
        }}
      >
        <Msg
          test={() => {
            this.handle();
          }}
          counter={this.state.counter}
        />
        {/* <input type="text" value={this.state.name} />
        <p>{this.state.age}</p> */}
      </div>
    );
  }
}

const Msg = props => {
  return (
    <div
      onClick={() => {
        props.test();
      }}
    >
      {props.counter}
    </div>
  );
};

export default TestHandle;

(生命周期&)

生命周期&

component生命周期

componentDidMount()已经挂载函数

state改变通过shouldComponentUpdate进行比对更新,return true往下执行

Initialization初始化props和state,之后Mounting挂载,之后Updation更新阶段,

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wespten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值