react【一】 传参

文章目录

  • 一、认识React
    • 1、第一个react程序
    • 2、使用组件重构代码
    • 3、遍历列表案例
    • 4、计数器案例
    • 5、为什么React选择了JSX
    • 6、this的绑定问题
  • 二、传参
    • 2.1 事件参数传递
    • 2.2 传参的案例
  • 三、生命周期
  • 四、组件之间传递参数
    • 1、父传子
    • 2、子传父
    • 3、案例
    • 4、剧名插槽
    • 5、作用域插槽
    • 6、context

一、认识React

1、第一个react程序

react【一】 传参_第1张图片

<body>
  <div id="root"></div>
  
  <!-- 引入依赖 -->
  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> 
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

  <!-- 编写React代码 -->
  <script type="text/babel">
    const root = ReactDOM.createRoot(document.querySelector("#root"))

    // 1.将文本定义成变量
    let message = "Hello World"

    // 2.监听按钮的点击
    function btnClick() {
      // 1.1.修改数据
      message = "Hello React"

      // 2.重新渲染界面
      rootRender()
    }

    // 3.封装一个渲染函数
    function rootRender() {
      root.render((
        <div>
          <h2>{message}</h2>
          <button onClick={btnClick}>修改文本</button>
        </div>
      ))
    }
    rootRender()
  </script>

</body>

2、使用组件重构代码

react【一】 传参_第2张图片

<body>

  <div id="root"></div>

  <script src="../lib/react.js"></script>
  <script src="../lib/react-dom.js"></script>
  <script src="../lib/babel.js"></script>

  <script type="text/babel">

    // 使用组件进行重构代码
    // 类组件和函数式组件
    class App extends React.Component {
      // 组件数据
      constructor() {
        super()
        this.state = {
          message: "Hello World",

          name: "why",
          age: 18
        }

        // 对需要绑定的方法, 提前绑定好this
        this.btnClick = this.btnClick.bind(this)
      }

      // 组件方法(实例方法)
      btnClick() {
        // 内部完成了两件事情: 
        // 1.将state中message值修改掉 2.自动重新执行render函数函数
        this.setState({
          message: "Hello React"
        })
      }

      // 渲染内容 render方法
      render() {
        return (
          <div>
            <h2>{this.state.message}</h2>
            <button onClick={this.btnClick}>修改文本</button>
          </div>
        )
      }
    }

    // this绑定的问题
    // const app = new App()
    // const foo = app.btnClick
    // foo(); // 默认绑定 => window => 严格模式下 => undefined

    // function bar() {
    //   console.log("bar:", this);
    // }
    // bar()


    // 将组件渲染到界面上
    const root = ReactDOM.createRoot(document.querySelector("#root"))
    // App根组件
    root.render(<App/>)


  </script>

</body>

3、遍历列表案例

<body>
  
  <div id="root"></div>

  <script src="../lib/react.js"></script>
  <script src="../lib/react-dom.js"></script>
  <script src="../lib/babel.js"></script>

  <script type="text/babel">
    // 1.创建root
    const root = ReactDOM.createRoot(document.querySelector("#root"))

    // 封装App组件
    class App extends React.Component {
      constructor() {
        super()

        this.state = {
          movies: ["星际穿越", "流浪地球", "独行月球", "大话西游", "火星救援"]
        }
      }


      render() {
        // 1.对movies进行for循环
        // const liEls = []
        // for (let i = 0; i < this.state.movies.length; i++) {
        //   const movie = this.state.movies[i]
        //   const liEl = 
  • {movie}
  • // liEls.push(liEl) // } // 2.movies数组 => liEls数组 // const liEls = this.state.movies.map(movie =>
  • {movie}
  • )
    return ( <div> <h2>电影列表</h2> <ul> {this.state.movies.map(movie => <li>{movie}</li>)} </ul> </div> ) } } // 2.渲染组件 root.render(<App/>) </script> </body>

    4、计数器案例

    <body>
      <div id="root"></div>
    
      <script src="../lib/react.js"></script>
      <script src="../lib/react-dom.js"></script>
      <script src="../lib/babel.js"></script>
    
      <script type="text/babel">
        const root = ReactDOM.createRoot(document.querySelector("#root"))
    
        class App extends React.Component {
          constructor() {
            super()
            this.state = {
              message: "Hello World",
              counter: 100
            }
    
            this.increment = this.increment.bind(this)
            this.decrement = this.decrement.bind(this)
          }
    
          render() {
            const { counter } = this.state
    
            return (
              <div>
                <h2>当前计数: {counter}</h2>
                <button onClick={this.increment}>+1</button>
                <button onClick={this.decrement}>-1</button>
              </div>
            )
          }
    
          // 组件的方法
          increment() {
            this.setState({
              counter: this.state.counter + 1
            })
          }
    
          decrement() {
            this.setState({
              counter: this.state.counter - 1
            })
          }
        }
    
        root.render(<App/>)
      </script>
    
    </body>
    

    5、为什么React选择了JSX

    react【一】 传参_第3张图片
    react【一】 传参_第4张图片
    react【一】 传参_第5张图片

    <body>
      
      <div id="root"></div>
    
      <script src="../lib/react.js"></script>
      <script src="../lib/react-dom.js"></script>
      <script src="../lib/babel.js"></script>
    
      <script type="text/babel">
        // 1.定义App根组件
        class App extends React.Component {
          constructor() {
            super()
            this.state = {
              counter: 100,
              message: "Hello World",
              names: ["abc", "cba", "nba"],
    
              aaa: undefined,
              bbb: null,
              ccc: true,
    
              friend: { name: "kobe" },
    
              firstName: "kobe",
              lastName: "bryant",
    
              age: 20,
    
              movies: ["流浪地球", "星际穿越", "独行月球"]
            }
          }
    
          render() {
            // 1.插入标识符
            const { message, names, counter } = this.state
            const { aaa, bbb, ccc } = this.state
            const { friend } = this.state
    
            // 2.对内容进行运算后显示(插入表示)
            const { firstName, lastName } = this.state
            const fullName = firstName + " " + lastName
            const { age } = this.state
            const ageText = age >= 18 ? "成年人": "未成年人"
            const liEls = this.state.movies.map(movie => <li>{movie}</li>)
    
            // 3.返回jsx的内容
            return (
              <div>
                {/* 1.Number/String/Array直接显示出来 */}
                <h2>{counter}</h2>
                <h2>{message}</h2>
                <h2>{names}</h2>
    
                {/* 2.undefined/null/Boolean */}
                <h2>{String(aaa)}</h2>
                <h2>{bbb + ""}</h2>
                <h2>{ccc.toString()}</h2>
    
                {/* 3.Object类型不能作为子元素进行显示*/}
                <h2>{friend.name}</h2>
                <h2>{Object.keys(friend)[0]}</h2>
    
                {/* 4.可以插入对应的表达式*/}
                <h2>{10 + 20}</h2>
                <h2>{firstName + " " + lastName}</h2>
                <h2>{fullName}</h2>
    
                {/* 5.可以插入三元运算符*/}
                <h2>{ageText}</h2>
                <h2>{age >= 18 ? "成年人": "未成年人"}</h2>
    
                {/* 6.可以调用方法获取结果*/}
                <ul>{liEls}</ul>
                <ul>{this.state.movies.map(movie => <li>{movie}</li>)}</ul>
                <ul>{this.getMovieEls()}</ul>
              </div>
            )
          }
    
          getMovieEls() {
            const liEls = this.state.movies.map(movie => <li>{movie}</li>)
            return liEls
          }
        }
    
        // 2.创建root并且渲染App组件
        const root = ReactDOM.createRoot(document.querySelector("#root"))
        root.render(<App/>)
      </script>
    
    </body>
    
    <body>
      
      <div id="root"></div>
    
      <script src="../lib/react.js"></script>
      <script src="../lib/react-dom.js"></script>
      <script src="../lib/babel.js"></script>
    
      <script type="text/babel">
        // 1.定义App根组件
        class App extends React.Component {
          constructor() {
            super()
            this.state = {
              title: "哈哈哈",
              imgURL: "https://ts1.cn.mm.bing.net/th/id/R-C.95bc299c3f1f0e69b9eb1d0772b14a98?rik=W5QLhXiERW4nLQ&riu=http%3a%2f%2f20178405.s21i.faiusr.com%2f2%2fABUIABACGAAgoeLO-wUo4I3o2gEw8Qs4uAg.jpg&ehk=N7Bxe9nqM08w4evC2kK6yyC%2bxIWTjdd6HgXsQYPbMj0%3d&risl=&pid=ImgRaw&r=0",
              href: "https://www.baidu.com",
              isActive: true,
              objStyle: {color: "red", fontSize: "30px"}
            }
          }
    
          render() {
            const { title, imgURL, href, isActive, objStyle } = this.state
    
            // 需求: isActive: true -> active
            // 1.class绑定的写法一: 字符串的拼接
            const className = `abc cba ${isActive ? 'active': ''}`
            // 2.class绑定的写法二: 将所有的class放到数组中
            const classList = ["abc", "cba"]
            if (isActive) classList.push("active")
            // 3.class绑定的写法三: 第三方库classnames -> npm install classnames
    
            return (
              <div>
                { /* 1.基本属性绑定 */ }
                <h2 title={title}>我是h2元素</h2>
                {/**/}
                <a href={href}>百度一下</a>
    
                
                { /* 2.绑定class属性: 最好使用className */ }
                <h2 className={className}>哈哈哈哈</h2>
                <h2 className={classList.join(" ")}>哈哈哈哈</h2>
    
                
                { /* 3.绑定style属性: 绑定对象类型 */ }
                <h2 style={{color: "red", fontSize: "30px"}}>呵呵呵呵</h2>
                <h2 style={objStyle}>呵呵呵呵</h2>
              </div>
            )
          }
        }
    
        // 2.创建root并且渲染App组件
        const root = ReactDOM.createRoot(document.querySelector("#root"))
        root.render(<App/>)
      </script>
    
    </body>
    

    6、this的绑定问题

    react【一】 传参_第6张图片

    <body>
      
      <div id="root"></div>
    
      <script src="../lib/react.js"></script>
      <script src="../lib/react-dom.js"></script>
      <script src="../lib/babel.js"></script>
    
      <script type="text/babel">
        // const obj = {
        //   name: "obj",
        //   foo: function() {
        //     console.log("foo:", this)
        //   }
        // }
    
        // // obj.foo()
    
        // const config = {
        //   onClick: obj.foo.bind(obj)
        // }
    
        // const click = config.onClick
        // click()
    
        /*
          this的四种绑定规则:
            1.默认绑定 独立执行 foo()
            2.隐式绑定 被一个对象执行 obj.foo() -> obj
            3.显式绑定: call/apply/bind foo.call("aaa") -> String("aaa")
            4.new绑定: new Foo() -> 创建一个新对象, 并且赋值给this
        */
    
        // 1.定义App根组件
        class App extends React.Component {
          // class fields
          name = "App"
    
          constructor() {
            super()
            this.state = {
              message: "Hello World",
              counter: 100
            }
    
            this.btn1Click = this.btn1Click.bind(this)
          }
    
          btn1Click() {
            console.log("btn1Click", this);
            this.setState({ counter: this.state.counter + 1 })
          }
    
          btn2Click = () => {
            console.log("btn2Click", this)
            this.setState({ counter: 1000 })
          }
    
          btn3Click() {
            console.log("btn3Click", this);
            this.setState({ counter: 9999 })
          }
    
          render() {
            const { message } = this.state
    
            return (
              <div>
                {/* 1.this绑定方式一: bind绑定 */}
                <button onClick={this.btn1Click}>按钮1</button>
    
                
                {/* 2.this绑定方式二: ES6 class fields */}
                <button onClick={this.btn2Click}>按钮2</button>
    
    
                {/* 3.this绑定方式三: 直接传入一个箭头函数(重要) */}
                <button onClick={() => console.log("btn3Click")}>按钮3</button>
    
                <button onClick={() => this.btn3Click()}>按钮3</button>
    
    
                <h2>当前计数: {this.state.counter}</h2>
              </div>
            )
          }
        }
    
        // 2.创建root并且渲染App组件
        const root = ReactDOM.createRoot(document.querySelector("#root"))
        root.render(<App/>)
      </script>
    
    </body>
    

    二、传参

    2.1 事件参数传递

    react【一】 传参_第7张图片

    <body>
      
      <div id="root"></div>
    
      <script src="../lib/react.js"></script>
      <script src="../lib/react-dom.js"></script>
      <script src="../lib/babel.js"></script>
    
      <script type="text/babel">
    
        // function foo(name, age, height) {}
        // const bar = foo.bind("aaa", "kobe", 30)
        // bar("event")
    
        // 1.定义App根组件
        class App extends React.Component {
          constructor() {
            super()
            this.state = {
              message: "Hello World"
            }
          }
    
          btnClick(event, name, age) {
            console.log("btnClick:", event, this)
            console.log("name, age:", name, age)
          }
    
          render() {
            const { message } = this.state
    
            return (
              <div>
                {/* 1.event参数的传递 */}
                <button onClick={this.btnClick.bind(this)}>按钮1</button>
                <button onClick={(event) => this.btnClick(event)}>按钮2</button>
    
                
                {/* 2.额外的参数传递 */}
                <button onClick={this.btnClick.bind(this, "kobe", 30)}>按钮3(不推荐)</button>
    
                <button onClick={(event) => this.btnClick(event, "why", 18)}>按钮4</button>
              </div>
            )
          }
        }
    
        // 2.创建root并且渲染App组件
        const root = ReactDOM.createRoot(document.querySelector("#root"))
        root.render(<App/>)
      </script>
    
    </body>
    

    2.2 传参的案例

    <body>
        <div id="root">div>
        <script src="../lib/react.js">script>
        <script src="../lib/react-dom.js">script>
        <script src="../lib/babel.js">script>
    
        <script type="text/babel">
            class App extends React.Component {
            constructor() {
              super();
              this.state = {
                movies: ["星际穿越", "盗梦空间", "大话西游", "流浪地球"],
                currentIndex: 0,
              };
            }
            handleClick(index) {
              this.setState({
                currentIndex: index,
              });
            }
    
            // render() {
            //   const { movies, currentIndex } = this.state;
            //     const lis = movies.map((item,index)=>{
            //         return (
            //             
  • // key={index} // onClick={()=>this.handleClick(index)} // > // {item} //
  • // ) // }) // return ( //
    //
      // {lis} //
    //
    // ) // } render(){ const {movies,currentIndex} = this.state const mapLis = (item,index) =>{ return ( <li className = {currentIndex ==index?'active':''} key={index} onClick={()=>this.handleClick(index)} > {item} </li>) } return ( <div> <ul>{movies.map(mapLis)}</ul> </div> ) } } const root = ReactDOM.createRoot(document.querySelector("#root")); root.render(<App/>)
    script> body>

    三、生命周期

    react【一】 传参_第8张图片

    react【一】 传参_第9张图片

    import React from "react";
    import HelloWord from "./HelloWord";
    
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          isShow: true,
        };
      }
      handleRemove() {
        const { isShow } = this.state;
        this.setState({ isShow: !isShow });
      }
      render() {
        const { isShow } = this.state;
        return (
          <div>
            <button onClick={() => this.handleRemove()}>点击卸载组件</button>
            {isShow && <HelloWord />}
          </div>
        );
      }
    }
    
    export default App;
    
    
    import React from "react";
    
    class HelloWord extends React.Component {
      // 1.先执行构造方法
      constructor() {
        super();
        this.state = {
          number: 1,
          isShow: true,
        };
      }
      handleClick() {
        const { number } = this.state;
        this.setState({ number: number + 1 });
      }
    
      // 2.执行render函数
      render() {
        const { number } = this.state;
        return (
          <div>
            <button onClick={() => this.handleClick()}>点击更新</button>
            <h1>{number}</h1>
          </div>
        );
      }
    
      // 3.组件被渲染到DOM:被挂载到DOM
      componentDidMount() {
        console.log("组件被挂载");
      }
    
      // 4.Dom发生更新
      // 第一个参数 更新前的props 更新前的state 获取dom更新前的信息
      componentDidUpdate(preProps, preState, snapShot) {
        console.log("Dom元素发生了更新");
        console.log(preProps, preState, snapShot);
      }
    
      // 5.组件被卸载掉
      componentWillUnmount() {
        console.log("组件发生了卸载");
      }
    
      // 不常用的生命周期 用来保存dom更新前的信息
      getSnapshotBeforeUpdate() {
        console.log("获取dom更新前的信息");
        return {
          scrollTop: 100,
        };
      }
    }
    
    export default HelloWord;
    
    

    react【一】 传参_第10张图片

    react【一】 传参_第11张图片
    react【一】 传参_第12张图片
    react【一】 传参_第13张图片

    四、组件之间传递参数

    1、父传子

    • APP.jsx
    import React, { Component } from "react";
    import Son from "./components/Son";
    
    export class App extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
      render() {
        return (
          <div>
            <Son title={["我是标题"]}></Son>
          </div>
        );
      }
    }
    
    export default App;
    
    • son.jsx
    import React, { Component } from "react";
    import PropTypes from "prop-types";
    
    export class Son extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
    
      render() {
        const { title } = this.props;
        return <div>{title}</div>;
      }
    }
    
    // 对传入的props设置默认值
    Son.defaultProps = {
      title: "默认标题",
    };
    
    // 对传入的props类型进行验证
    Son.propTypes = {
      title: PropTypes.string,
    };
    
    export default Son;
    
    

    2、子传父

    react【一】 传参_第14张图片

    • App.jsx
    import React, { Component } from "react";
    import Son from "./Son";
    
    class App extends Component {
      constructor() {
        super();
        this.state = {
          counter: 20,
        };
      }
    
      changeCounter(value) {
        this.setState({ counter: this.state.counter + value });
      }
    
      render() {
        const { counter } = this.state;
        return (
          <div>
            <h1>当前计数为{counter}</h1>
            <Son changeCounterFun={(counter) => this.changeCounter(counter)}>
              +1
            </Son>
          </div>
        );
      }
    }
    
    export default App;
    
    
    • Son.jsx
    import React, { Component } from "react";
    
    class Son extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
    
      changeCounter(value) {
        const { changeCounterFun } = this.props;
        changeCounterFun(value);
      }
    
      render() {
        return (
          <div>
            <button onClick={() => this.changeCounter(+1)}>+1</button>
            <button onClick={() => this.changeCounter(-1)}>+1</button>
          </div>
        );
      }
    }
    
    export default Son;
    
    

    3、案例

    react【一】 传参_第15张图片

    react【一】 传参_第16张图片

    • son.jsx
    import React, { Component } from "react";
    import "./Son.css";
    
    export class Son extends Component {
      constructor(props) {
        super(props);
        this.state = {
          currentIndex: 0,
        };
      }
    
      changeTab(index) {
        const { currentIndex } = this.state;
        console.log("发射", currentIndex);
        this.setState({ currentIndex: index });
        this.props.changeTabFun(currentIndex);
      }
      render() {
        const { currentIndex } = this.state;
        const activeClass = (index) => {
          if (index === currentIndex) return true;
          else return false;
        };
    
        const tabs = this.props.tabs;
        const tabsDom = tabs.map((item, index) => (
          <div
            className={`tab ${activeClass(index) ? "active" : ""}`}
            key={index}
            onClick={() => this.changeTab(index)}
          >
            {item},{index}
          </div>
        ));
    
        return <div className="tabs">{tabsDom}</div>;
      }
    }
    
    export default Son;
    
    
    

    4、剧名插槽

    react【一】 传参_第17张图片

    import React, { Component } from "react";
    import "./Son.css";
    
    export class Son extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
      render() {
        const { children } = this.props;
        const { slotLeft, slotRight, slotCenter } = this.props;
        return (
          <div>
            {children}
            <div className="tabs">
              <div className="tab">{slotLeft}</div>
              <div className="tab">{slotCenter}</div>
              <div className="tab">{slotRight}</div>
            </div>
          </div>
        );
      }
    }
    
    export default Son;
    
    

    react【一】 传参_第18张图片

    5、作用域插槽

    react【一】 传参_第19张图片
    react【一】 传参_第20张图片

    6、context

    react【一】 传参_第21张图片
    react【一】 传参_第22张图片
    react【一】 传参_第23张图片
    ![在这里插入图片描述](https://img-blog.csdnimg.

    import React from "react";
    
    // 1、创建一个Context
    const userContext = React.createContext();
    
    export default userContext;
    
    

    App.jsx

    import React, { Component } from "react";
    import User from "./components/User";
    
    import userContext from "./context/user-context";
    
    class App extends Component {
      constructor() {
        super();
        this.state = {
          info: {
            name: "APP.JSX",
            age: 18,
          },
        };
      }
      render() {
        const { info } = this.state;
        return (
          <div>
            {/* 第2步骤 通过value为后代提供组件 */}
            <userContext.Provider value={{ nickName: "kiki", age: 18 }}>
              <User {...info}></User>
            </userContext.Provider>
          </div>
        );
      }
    }
    
    export default App;
    
    
    • user.jsx
    import React, { Component } from "react";
    
    import userContext from "../context/user-context";
    
    export class User extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
      render() {
        const { name, age } = this.props;
        return (
          <div>
            <h1>
              props传进来的值:{name},{age}
            </h1>
            {/* 4、使用上下文的数值 */}
            <h1>通过context传进来的值:{this.context.nickName}</h1>
    
            {/* 也可以通过消费者来获取值 */}
            <userContext.Consumer>
              {(value) => {
                return value.nickName;
              }}
            </userContext.Consumer>
          </div>
        );
      }
    }
    
    // 3、引入上下文
    User.contextType = userContext;
    
    export default User;
    
    ``
    

    你可能感兴趣的:(react,react.js,javascript,前端)