react框架基础

react 框架基础

1. 声明式渲染

 <!-- react 的核心库 -->
    <script src="./libs/react.development.js"></script>
    <!-- 提供与DOM相关的功能 -->
    <script src="./libs/react-dom.development.js"></script>
    <!-- babel编译器,转码器,主要负责把react中的代码, 现代浏览器不能直接运行,需要转换.生产环境中不建议使用-->
    <script src="./libs/babel.min.js"></script>
</head>
<body>
    <!-- 2. 创建容器,用来渲染其他元素或将来封装的组件 -->
    <div id="app"></div>
    <!-- 3. 实现:就是通过引入的脚本在容器中渲染其他元素或组件 -->
    <!-- jsx语法中的注释,jsx语法中的插值语法 -->
    <script type="text/babel">
        let element = (
            // 单根元素
            <div>
            {/*这才是注释,两个花括号是插值语法*/}
            {1+1}-{true?"成立":"不成立"}
            </div>
        )
        ReactDOM.render(element,document.querySelector("#app"))
    </script>
</body>

2. 组件封装(函数组件,类组件)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  </head>
  <body>
    <div id="app"></div>

    <script type="text/babel">
      // 1。函数组件
      function Login() {
        // 返回视图,视图用啥定义?jsx

        return (
          <div>
            {/*标签必须正确闭合*/}
            {/*for在js中是关键字,使用htmlFor, class=>className*/}
            <label htmlFor="acc" className="red">
              账号
            </label>
            <input type="text" id="acc" />
            <br />
            <input type="password" />
            <br />
            <button>登录</button>
          </div>
        );
      }

      // 2。类组件
      class Login2 extends React.Component {
        // 渲染函数
        render() {
          return (
            <div>
              {/*标签必须正确闭合*/}
              {/*for在js中是关键字,使用htmlFor, class=>className*/}
              <label htmlFor="acc" className="red">
                账号2
              </label>
              <input type="text" id="acc" />
              <br />
              <input type="password" />
              <br />
              <button>登录</button>
            </div>
          );
        }
      }

      ReactDOM.render(<Login2></Login2>, document.querySelector("#app"));
    </script>
  </body>
</html>

3.父子组件传值

 <body>
    <div id="app"></div>
    <script type="text/babel">
      // props 接收父组件传递的数据
      function Person(props) {
        return (
          <div>
            {/*
            <p>名称:{props.name}</p>    
            <p>年龄:{props.age}</p>    
            <p>性别:{props.sex}</p> 
            */}
            <p>名称:{props.person.name}</p>
            <p>年龄:{props.person.age}</p>
            <p>性别:{props.person.sex}</p>
          </div>
        );
      }

      class Person2 extends React.Component {
        render(props) {
          //   console.log(this);
          let { name, age, sex } = this.props.person;
          return (
            <div>
              {/*
              <p>名称:{this.props.person.name}</p>
              <p>年龄:{this.props.person.age}</p>
              <p>性别:{this.props.person.sex}</p>
              */}
              <p>名称:{name}</p>
              <p>年龄:{age}</p>
              <p>性别:{sex}</p>
            </div>
          );
        }
      }
      let zs = { name: "张三", age: 16, sex: "男" };
      ReactDOM.render(
        // <Person name="张三" age="18" sex="男" />,
        // react没有指令.使用插值语法绑定动态值
        <Person person={zs} />,
        document.querySelector("#app")
      );
    </script>
  </body>

4.类组件事件绑定,双向数据绑定,定义更改数据

 <body>
    <div id="app"></div>
    <script type="text/babel">
      class Login extends React.Component {
        // 类的构造函数
        constructor() {
          // 在本类Login调用super()超类,相当于去调用父类React.Component的构造函数。
          // 为啥? 类实例化时有一个顺序,进入时  Login->React.Component,执行时React.Component->Login
          super();

          // 设置数据
          this.state = {
            account: "admin2",
            password: "111111",
          };

          // 2。事件绑定
          // 在构造函数中使用bind纠正this, 让myLogin()方法中的this指向当前组件
          this.abc = this.myLogin.bind(this);
        }

        // 这样也可以设置数据
        /* state = {
          account: "admin",
          password: "123456",
        }; */

        // 渲染函数
        render() {
          return (
            <div>
              <p>事件绑定的两种方式:</p>
              <p>1. 直接定义箭头函数,视图中直接调用箭头函数</p>
              <p>2. 定义成类的方法,在构造函数中定义一个属性,初始化成方法,并纠正this指向,在视图中调用构造函数中的属性。</p>

              <p>双向数据绑定:</p>
              <p>开发者自行控制value属性和change事件</p>
              <p>注意事件对象的使用</p>


              <p>在类组件中定义数据的方式</p>
              <p>1. 在构造函数中,如this.state=xxx</p>
              <p>2. 直接在类中定义属性  state=xxx</p>
              <p>3. setState()来更改state</p>
              {/*标签必须正确闭合*/}
              {/*for在js中是关键字,使用htmlFor, class=>className*/}
              <label htmlFor="acc" className="red">
                账号:{this.state.account}
              </label>
              {/*
                react中没有指令,所以v-model这种用法不能实现,需要开发者手动控制value和onchange事件
                在react框架中实现双向数据绑定需要手动控制value和onchange事件。
                事件名称格式, onchange=>onChange onclick=>onClick
              */}
              <input
                type="text"
                id="acc"
                value={this.state.account}
                onChange={this.changeAccount}
              />
              <br />
              <label htmlFor="pwd" className="red">
                密码:{this.state.password}
              </label>

              {/*不建议在视图中直接编写业务逻辑。*/}
              <input
                type="password"
                id="pwd"
                value={this.state.password}
                onChange={(e) => {
                  this.setState({ password: e.target.value });
                }}
              />
              <br />
              <button onClick={this.abc}>登录</button>
            </div>
          );
        }

        myLogin(){
          // 注意this指向
          console.log(this.state.account)
        }

        // 1. 绑定事件  使用箭头函数
        // e=>event事件对象,通过事件对象可以拿到操作的元素(目标元素)
        changeAccount = (e) => {
          console.log(e.target.value);
          // this.state.account = e.target.value; // 错误的写法
          // setState()就react看唯一一种更改state数据的方式。且支持响应式。
          this.setState({
            account: e.target.value,
          });
        };
      }
      ReactDOM.render(<Login />, document.querySelector("#app"));
    </script>
  </body>

5.自定义属性, 操作style,class

  <style>
      .red{
        color: red
      }
   </style>
   
   <body>
    <div id="app"></div>

    <script type="text/babel">
      // 函数组件中如何定义数据??使用hook
      function Com1(props) {
        console.log(props);
        let style = { border: "1px solid red", fontSize: 20 };
        let red = "red"
        return (
          <div style={style} className={red}>
            <div>自定义</div>
          </div>
        );
      }
      ReactDOM.render(
        <Com1 data-dsh="dong shu hua" dsh="董书华" />,
        document.querySelector("#app")
      );
    </script>
  </body>

6.生命周期,循环

 <div id="app"></div>
//products.json
{
    "products": [
        {"id": 1, "name": "苹果手机", "price": 8000},
        {"id": 2, "name": "华为手机", "price": 8000}
    ]
}
 <script type="text/babel">
      class ProductList extends React.Component {
        render() {
          console.log("render渲染函数执行,也是一个生命周期");
          /* return (
            <div className="product">
              {
                this.state.products.map((p) => {
                  return <div className="item" key={p.id}>{p.id}-{p.name}-{p.price}</div>;
                })
              }
            </div>
          ); */

          /* let lists = [];
          for (let i = 0; i < this.state.products.length; i++) {
            const p = this.state.products[i];
            let item = <div className="item" key={p.id}>{p.id}-{p.name}-{p.price}</div>;
            lists.push(item)
          } */

          /* let lists = this.state.products.map((p) => (
            <div className="item" key={p.id}>
              {p.id}-{p.name}-{p.price}
            </div>
          )); */

          let lists = [];
          this.state.products.forEach((p) => {
            let item = (
              <div className="item" key={p.id}>
                {p.id}-{p.name}-{p.price}
              </div>
            );
            lists.push(item);
          });

          return <div className="product">{lists}</div>;
        }

        // 组件的数据
        state = {
          products: [], //存储商品列表
        };

        // 生命周期,相当于vue中的mounted
        componentDidMount() {
          console.log("componentDidMount执行。");
          this.getProducts();
        }

        async getProducts() {
          let result = await window
            .fetch("data/products.json")
            .then((res) => res.json());
          console.log(result);

          this.setState({
            products: result.products,
          });
        }
      }
      ReactDOM.render(<ProductList />, document.querySelector("#app"));
    </script>

7.生命周期

   <script type="text/babel">
      class Com1 extends React.Component {
        // props用来接收外部传递的数据
        constructor(props) {
          console.log("1。构造函数中,初始化props和state");
          // 初始化外部传递的数据props
          super(props);
          // 初始化组件自身的数据state
          this.state = {
            products:[],
            count: 1,
          };
        }
        render() {
          console.log("3。render渲染函数,数据发生变化render重新执行");
          return (
            <div>
              <p>生命周期</p>
              <p>{this.state.count}</p>
              <button onClick={this.add}>累加</button>
            </div>
          );
        }

        add = ()=>{
          this.setState({
            count: this.state.count+1
          })
        }
        // 相当于vue中的beforeMount, component组件, will即将,mount渲染,准备好。
        // 警告:componentWillMount has been renamed, and is not recommended for use
        componentWillMount() {
          console.log("2。组件渲染前执行,可以在此处拉取数据");

          this.setState({
            products: [1, 2, 3],
          });
        }

        componentDidMount() {
          console.log("4。组件渲染后执行,可以在此处拉取数据");
        }
        componentWillUpdate(){
          console.log("5。数据更新前执行")
        }
        componentDidUpdate(){
          console.log("6。数据更新后执行")
        }
        shouldComponentUpdate(){
          // 一般通过在sholdComponentUpdate生命周期中返回False,减少render函数的执行,从而达到渲染性能的提升。
          // 一般使用在视图中不使用数据state|props的情况下。
          console.log("4.5。shouldComponentUpdate返回一个布尔值,返回true,让组件更新,返回false不让组件更新")
          return false
        }
        // 相当于vue中的beforeDestory()。用来清楚定时器,window全局事件。如:window.onscoll
        componentWillUnMount(){
          console.log("组件消毁前执行。")
        }
      }
      ReactDOM.render(<Com1 />, document.querySelector("#app"));
    </script>

8.生命周期

 <script type="text/babel">
      class BigCom extends React.Component {
        state = {
          name: 'hello'
        }
        render() {
          return (
            <div>
              <h1>大组件</h1>
              <button onClick={this.changeName}>更新dsh</button>
              <Com dsh={this.state.name} />
            </div>
          );
        }
        changeName=()=>{
          this.setState({
            name: "HELLO"
          })
        }
      }
      class Com extends React.Component {
        constructor(props){
          console.log("1.构造函数")
          super(props)
        }
        render() {
          console.log("2.渲染函数")
          return (
            <div>
              <h1>小组件{this.props.dsh}</h1>
            </div>
          );
        }
        // Warning: componentWillReceiveProps has been renamed, and is not recommended for use
        // 推荐使用componentDidUpdate
        /* componentWillReceiveProps(){
          console.log("即将接收props时执行")
        } */
        componentWillUpdate(){
          console.log("数据state|props发生变化前执行")
        }
        componentDidUpdate(){
          console.log("数据state|props发生变化后执行")
        }
      }
      ReactDOM.render(<BigCom />, document.querySelector("#app"));
    </script>

9.阻止默认行为

 <script type="text/babel">
      class Com extends React.Component {
        render() {
          let html = { __html: '<a href="javascript:void(0);">百度</a>' };
          return (
            <div>
              <a href="https://www.baidu.com">百度</a>
              <br />

              {/*v-html和v-text*/}
              <div dangerouslySetInnerHTML={html}></div>

              <form action="https://www.sina.com.cn" onSubmit={this.submit}>
                <input type="text" />
                <button>提交</button>
              </form>

              {/*alt必写,不写时在脚手架中报错*/}
              <img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" alt="" />
            </div>
          );
        }

        go = () => {
          location.href = "https://www.baidu.com";
        };

        submit = (e)=>{
          e.preventDefault();
          console.log("e.preventDefault()可以阻止form的默认行为")
        }
      }
      ReactDOM.render(<Com />, document.querySelector("#app"));
    </script>
posted @ 2021-11-24 19:23  水波凌步  阅读(235)  评论(0)    收藏  举报