Bootstrap

React系统学习

react是facebook开源的,为什么高效的原因,是因为使用了虚拟dom技术,可以很大程度的复用。

1.基本语法

helloWorld,babel的引入是为了将jsx转换为js,使用jsx可以更快的创建虚拟dom。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>hello_react</title>
</head>

<body>
    <div id="test"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
        const VDOM = <h1>hello,React</h1> 
        ReactDOM.render(VDOM,document.getElementById('test')) /*此处不写引号,不是字符串*/
    </script>
</body>

</html>

JSX的基本语法:

  • 定义虚拟DOM时,不要写引号
  • 标签中混入JS表达式要用{},注意用const xxx=可以接收的才叫表达式
  • 样式的类名指定不要用class,要用className
  • 内联样式,要用style={{key:value}}形式
  • 只有一个根标签
  • 标签必须闭合
  • 标签首字母:
    (1)若小写字母开头,则把标签转化为html同名元素,若没有对应同名元素则报错
    (2)若大写字母开头,react就去渲染对应的组件,若组件没有定义则报错。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>hello_react</title>
</head>
<style>
    .title {
        font-size: large;
        color: blue;
    }
</style>

<body>
    <div id="test"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
        const title = 'title'
        const VDOM = (
            <div>
                <h1 className={title} style={{ color: 'red' }}>
                    <span>hello,React</span>
                </h1>
                <Good></Good>
            </div>

        )
        ReactDOM.render(VDOM, document.getElementById('test')) /*此处不写引号,不是字符串*/
    </script>
</body>

</html>

2.面向组件编程

js的模块化只是拆分html,而组件编程则是html、css、js、img、video等整合起来是一个组件,优点是复用编码,提高效率。

2.1函数式组件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello_react</title>
  </head>
  <style>
    .title {
      font-size: large;
      color: blue;
    }
  </style>

  <body>
    <div id="test"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script
      type="text/javascript"
      src="../js/react-dom.development.js"
    ></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
      function Demo() {
        return <h1>我是一个函数式组件(适用于简单的自定义)</h1>;
      }
      ReactDOM.render(<Demo />, document.getElementById("test"));
    </script>
  </body>
</html>

2.2类式组件

2.2.1类的初识
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello_react</title>
  </head>
  <style>
    .title {
      font-size: large;
      color: blue;
    }
  </style>

  <body>
    <div id="test"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script
      type="text/javascript"
      src="../js/react-dom.development.js"
    ></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
      // 创建一个Person类
      class Perseon {
        // 构造器方法
        constructor(name, age) {
          this.name = name;
          this.age = age;
        }
        // 一般方法
        speak() {
          // speak方法在类的原型对象上,供实例使用
          // 通过Person实例调用speak时,speak中的this就是Person实例
          console.log(`我叫${this.name},我已经${this.age}`);
        }
      }

      class Student extends Perseon {
        constructor(name, age, grade) {
          // 子类使用构造器一定要使用super且必须在前面
          super(name, age);
          this.grade = grade;
        }
        // 重写父类继承的方法
        speak(name,age,grade){
          console.log(`我叫${this.name},我已经${this.age}了,在读${this.grade}`);
        }
      }
      const mm = new Perseon("小满", 10);
      console.log(mm);
      mm.speak();
      //   call可以更改函数里的this指向
      mm.speak.call({ name: "didi", age: 8 });

      const ls = new Student("李四", "18", "大一");
      ls.speak();
    </script>
  </body>
</html>

2.2.2使用

React解析组件标签时,发现组件是使用类定义的,会new出该类实例,并通过该实例调用到原型上的render

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello_react</title>
  </head>
  <style>
    .title {
      font-size: large;
      color: blue;
    }
  </style>

  <body>
    <div id="test"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script
      type="text/javascript"
      src="../js/react-dom.development.js"
    ></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
      class MyComponent extends React.Component{
        render(){
            return '我是一个类式组件'
        }
      }

      ReactDOM.render(<MyComponent/>,document.getElementById('test'))
    </script>
  </body>
</html>

3.State状态

借助构造器初始化状态并使用,通过点击事件修改状态。

标准写法(强制绑定)

下面是标准写法,借助构造器的this对state进行初始化

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello_react</title>
  </head>
  <style>
    .title {
      font-size: large;
      color: blue;
    }
  </style>

  <body>
    <div id="test"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script
      type="text/javascript"
      src="../js/react-dom.development.js"
    ></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
      class Weather extends React.Component {
        constructor(props) {
          super(props);
          //   初始化状态
          this.state = { isHot: true, wind: "微风" };
          //   解决changeWeather中指向问题
          this.changeWeather = this.changeWeather.bind(this);
        }
        render() {
          const { isHot, wind } = this.state;
          return (
            <h1 onClick={this.changeWeather}>
              今天天气{isHot ? "炎热" : "凉爽"}{wind}
            </h1>
          );
        }

        changeWeather() {
          const isHot = this.state.isHot;
          this.setState({ isHot: !isHot });
          console.log("修改天气:", this.state.isHot);
        }
      }

      ReactDOM.render(<Weather />, document.getElementById("test"));
    </script>
  </body>
</html>

在这里插入图片描述

在这里插入图片描述

简化写法(箭头函数)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello_react</title>
  </head>
  <style>
    .title {
      font-size: large;
      color: blue;
    }
  </style>

  <body>
    <div id="test"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script
      type="text/javascript"
      src="../js/react-dom.development.js"
    ></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
      class Weather extends React.Component {
        // 自定义状态
        state = { isHot: true, wind: "微风" };
        render() {
          const { isHot, wind } = this.state;
          return (
            <h1 onClick={this.changeWeather}>
              今天天气{isHot ? "炎热" : "凉爽"}{wind}
            </h1>
          );
        }

        // 自定义方法——用赋值语句+箭头函数的形式
        changeWeather = () => {
          console.log(this);
          const isHot = this.state.isHot;
          this.setState({ isHot: !isHot });
          console.log("修改天气:", this.state.isHot);
        };
      }

      ReactDOM.render(<Weather />, document.getElementById("test"));
    </script>
  </body>
</html>

4.props多种属性

三点运算符…表示展开,是对于一个数组。

基本使用

{...Person}在原生es6语法中,表示克隆一个对象
{...Person,name:'jack'}表示克隆一个对象并替换
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>hello_react</title>
  </head>
  <body>
    <div id="test1"></div>
    <div id="test2"></div>
    <div id="test3"></div>
    <!-- 先引入核心库、扩展库、babel库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script
      type="text/javascript"
      src="../js/react-dom.development.js"
    ></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/babel">
      class Weather extends React.Component {
        render() {
          const { area, day, weather } = this.props;
          return (
            <ul>
              <li>{area}</li>
              <li>{day}</li>
              <li>{weather}</li>
            </ul>
          );
        }
      }

      const p = { area: "福州", day: "11月25日", weather: "晴" };
	  //这里不是表示克隆而是展开p,因为react+babel,原生会报错,而且只有标签属性可以
      ReactDOM.render(<Weather {...p} />, document.getElementById("test1"));

      ReactDOM.render(
        <Weather area="泉州" day="11月25日" weather="阴" />,
        document.getElementById("test2")
      );

      ReactDOM.render(
        <Weather area="厦门" day="11月25日" weather="大风" />,
        document.getElementById("test3")
      );
    </script>
  </body>
</html>

标签属性限制

      Person.propTypes = {
        name: PropTypes.string.isRequired,//限制name必传,且为字符串
        sex: PropTypes.string,//限制sex为字符串
        age: PropTypes.number,//限制age为数值
        speak:PropTypes.func//限制speak为函数
      };

      Person.defaultProps = {
        sex: "保密",//sex默认值保密
      };

简写

      class Person extends React.Component {
        static propTypes = {
          name: PropTypes.string.isRequired, //限制name必传,且为字符串
          sex: PropTypes.string, //限制sex为字符串
          age: PropTypes.number, //限制age为数值
          speak: PropTypes.func, //限制speak为函数
        };

        static defaultProps = {
          sex: "保密", //sex默认值保密
        };
        render() {
          const { name, sex, age } = this.props;
          return (
            <ul>
              <li>{name}</li>
              <li>{sex}</li>
              <li>{age + 1}</li>
            </ul>
          );
        }
      }

5.refs

正文

字符串形式

 class Demo extends React.Component {
        showData = () => {
          console.log(this);
          const {input1} = this.refs
          console.log(input1.value);
        };
        render() {
          return (
            <div>
              <input ref="input1" type="text" placeholder="点击按钮提示数据" />
              &nbsp;
              <button onClick={this.showData}>获取数据</button>&nbsp;
              <input id="input2" placeholder="失去焦点提示数据" />
            </div>
          );
        }
      }

      ReactDOM.render(<Demo />, document.getElementById("test1"));

回调函数形式

<script type="text/babel">
      class Demo extends React.Component {
        showData = () => {
          const { input1 } = this.refs;
          console.log(this.input1.value);
        };
        render() {
          return (
            <div>
              <input
                ref={(c) => (this.input1 = c)}
                type="text"
                placeholder="点击按钮提示数据"
              />
              &nbsp;
              <button onClick={this.showData}>获取数据</button>&nbsp;
            </div>
          );
        }
      }
      ReactDOM.render(<Demo />, document.getElementById("test1"));
</script>

回调函数形式

 myRef1 = React.createRef();
 
<input
  ref={this.myRef1}
  type="text"
  placeholder="点击按钮提示数据"
/>
<script type="text/babel">
      class Demo extends React.Component {
        state = { isHot: true };
        myRef1 = React.createRef();
        myRef2 = React.createRef();

        showData = () => {
          console.log(this.myRef1.current.value);
        };

        showData2 = () => {
          alert(this.myRef2.current.value);
        };

        changeWeather = () => {
          const { isHot } = this.state;
          this.setState({ isHot: !isHot });
        };
        render() {
          const { isHot } = this.state;

          return (
            <div>
              <h1>今天天气很{isHot ? "炎热" : "凉爽"}</h1>
              <input
                ref={this.myRef1}
                type="text"
                placeholder="点击按钮提示数据"
              />
              &nbsp;
              <button onClick={this.showData}>获取数据</button>
              &nbsp;
              <button onClick={this.changeWeather}>点击切换天气</button>&nbsp;
              <input
                onBlur={this.showData2}
                ref={this.myRef2}
                type="text"
                placeholder="失去焦点提示数据"
              />
              &nbsp;
            </div>
          );
        }
      }
      ReactDOM.render(<Demo />, document.getElementById("test1"));
    </script>
;