欢迎光临
我们一直在努力

React - 收集表单元素、收集表单元素优化、生命周期(旧)、生命周期(新)

一、收集表单元素

1、基本介绍
  • 使用受控组件:表单元素的值由 React 状态管理,需要 onChange 事件来更新状态

  • 使用非受控组件:表单元素的值由 DOM 管理,不需要 onChange 事件来更新状态

  • 2、演示
  • 使用受控组件
  • <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>受控组件</title>
    </head>

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

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
    class Login extends React.Component {
    state = {
    username: "",
    password: "",
    };

    saveUsername = (event) => {
    this.setState({
    username: event.target.value,
    });
    };

    savePassword = (event) => {
    this.setState({
    password: event.target.value,
    });
    };

    handleSubmit = (event) => {
    event.preventDefault(); // 阻止表单提交

    let { username, password } = this.state;
    alert(`你输入的用户名是:${username},你输入的密码是:${password}`);
    };

    render() {
    return (
    <form action="http://www.mytest.com" onSubmit={this.handleSubmit}>
    用户名:
    <input onChange={this.saveUsername} type="text" name="username" />
    密码:
    <input onChange={this.savePassword} type="password" name="password" />
    <button>登录</button>
    </form>
    );
    }
    }

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

  • 使用非受控组件
  • <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>非受控组件</title>
    </head>

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

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
    class Login extends React.Component {
    handleSubmit = (event) => {
    event.preventDefault(); // 阻止表单提交

    // 这里现用现取
    const { username, password } = this;
    alert(`你输入的用户名是:${username.value},你输入的密码是:${password.value}`);
    };

    render() {
    return (
    <form action="http://www.mytest.com" onSubmit={this.handleSubmit}>
    用户名:
    <input ref={(c) => (this.username = c)} type="text" name="username" />
    密码:
    <input ref={(c) => (this.password = c)} type="password" name="password" />
    <button>登录</button>
    </form>
    );
    }
    }

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


    二、收集表单元素优化

    1、基本介绍
  • 高阶函数:如果一个函数符合下面 2 个规范中的任何一个,那该函数就是高阶函数
  • 1. 若 A 函数,接收的参数是一个函数,那么 A 函数就可以称之为高阶函数

    2. 若 A 函数,调用的返回值依然是一个函数,那么 A 函数就可以称之为高阶函数

    * 常见的高阶函数有:Promise、setTimeout()、arr.map()

  • 函数柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式
  • 2、演示
  • 使用函数柯里化
  • <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>高阶函数与函数柯里化</title>
    </head>

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

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
    class Login extends React.Component {
    state = {
    username: "",
    password: "",
    };

    saveFormData = (dataType) => {
    return (event) => {
    this.setState({
    [dataType]: event.target.value,
    });
    };
    };

    handleSubmit = (event) => {
    event.preventDefault(); // 阻止表单提交

    let { username, password } = this.state;
    alert(`你输入的用户名是:${username},你输入的密码是:${password}`);
    };

    render() {
    return (
    <form action="http://www.mytest.com" onSubmit={this.handleSubmit}>
    用户名:
    <input onChange={this.saveFormData("username")} type="text" name="username" />
    密码:
    <input onChange={this.saveFormData("password")} type="password" name="password" />
    <button>登录</button>
    </form>
    );
    }
    }

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

  • 不使用函数柯里化
  • <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>不使用函数柯里化</title>
    </head>

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

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
    class Login extends React.Component {
    state = {
    username: "",
    password: "",
    };

    saveFormData = (dataType, event) => {
    this.setState({
    [dataType]: event.target.value,
    });
    };

    handleSubmit = (event) => {
    event.preventDefault(); // 阻止表单提交

    let { username, password } = this.state;
    alert(`你输入的用户名是:${username},你输入的密码是:${password}`);
    };

    render() {
    return (
    <form action="http://www.mytest.com" onSubmit={this.handleSubmit}>
    用户名:
    <input
    onChange={(event) => {
    this.saveFormData("username", event);
    }}
    type="text"
    name="username"
    />
    密码:
    <input
    onChange={(event) => {
    this.saveFormData("password", event);
    }}
    type="password"
    name="password"
    />
    <button>登录</button>
    </form>
    );
    }
    }

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


    三、生命周期(旧)

    1、基本介绍
  • 初始化阶段:由 ReactDOM.render() 触发初次渲染
  • 1. constructor()

    2. componentwillMount()

    3. render():必须使用

    4. componentDidMount():常用,一般在这个钩子中做一些初始化的事,例如:发送网络请求、开启定时器、订阅消息

  • 更新阶段:由组件内部 this.setsate() 或父组件重新 render() 触发
  • 1. shouldComponentUpdate()

    2. componentWillUpdate()

    3. render()

    4. componentDidUpdate()

  • 卸载组件:由 ReactDOM.unmountComponentAtNode() 触发
  • 1. componentwillUnmount():常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

    2、演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>生命周期(旧)</title>
    </head>

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

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
    class Count extends React.Component {

    // 构造器
    constructor(props) {
    console.log("Count: constructor");
    super(props);

    this.state = {
    count: 0,
    };
    }

    add = () => {
    let { count } = this.state;
    this.setState({
    count: count + 1,
    });
    };

    kill = () => {
    ReactDOM.unmountComponentAtNode(document.getElementById("test"));
    };

    force = () => {
    this.forceUpdate();
    };

    // 组件将要挂载的钩子
    componentWillMount() {
    console.log("Count: componentWillMount");
    }

    // 组件挂载完毕的钩子
    componentDidMount() {
    console.log("Count: componentDidMount");
    }

    // 组件将要卸载的钩子
    componentWillUnmount() {
    console.log("Count: componentWillUnmount");
    }

    // 控制组件更新的阀门
    shouldComponentUpdate() {
    console.log("Count: shouldComponentUpdate");
    return true;
    }

    // 组件将要更新的钩子
    componentWillUpdate() {
    console.log("Count: componentWillUpdate");
    }

    // 组件更新完毕的钩子
    componentDidUpdate() {
    console.log("Count: componentDidUpdate");
    }

    render() {
    console.log("Count: render");
    return (
    <div>
    <h2>当前求和为:{this.state.count}</h2>
    <button onClick={this.add}>点我 + 1</button>
    <br />
    <button onClick={this.kill}>卸载组件</button>
    <br />
    <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
    </div>
    );
    }
    }

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

  • 打开页面,输出结果如下
  • Count: constructor
    Count: componentWillMount
    Count: render
    Count: componentDidMount

  • 点击 【点我 + 1】 按钮,输出结果如下
  • Count: shouldComponentUpdate
    Count: componentWillUpdate
    Count: render
    Count: componentDidUpdate

  • 点击 【不更改任何状态中的数据,强制更新一下】,输出结果如下
  • Count: componentWillUpdate
    Count: render
    Count: componentDidUpdate

  • 点击 【卸载组件】 按钮,输出结果如下
  • Count: componentWillUnmount

    3、父组件更新 props 传递给子组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>生命周期(旧)</title>
    </head>

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

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">

    // 父组件 A
    class A extends React.Component {
    state = {
    carName: "奔驰",
    };

    changeCar = () => {
    this.setState({
    carName: "奥拓",
    });
    };

    render() {
    console.log("A: render");
    return (
    <div>
    <div>我是 A 组件</div>
    <button onClick={this.changeCar}>换车</button>
    <B carName={this.state.carName} />
    </div>
    );
    }
    }

    // 子组件 B
    class B extends React.Component {

    // 组件将要接收新的 props 的钩子
    // 第一次接收 props 不会调用,其实应该改为:componentWillReceiveProps()
    // UNSAFE_componentWillReceiveProps() 是 React 对 componentWillReceiveProps() 的渐进式迁移
    UNSAFE_componentWillReceiveProps(props) {
    console.log("B: componentWillReceiveProps", props);
    }

    shouldComponentUpdate() {
    console.log("B: shouldComponentUpdate");
    return true;
    }

    componentWillUpdate() {
    console.log("B: componentWillUpdate");
    }

    componentDidUpdate() {
    console.log("B: componentDidUpdate");
    }

    render() {
    console.log("B: render");
    return (
    <div>
    <div>我是 B 组件</div>
    <div>接收到的车是:{this.props.carName}</div>
    </div>
    );
    }
    }

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

  • 打开页面,输出结果如下
  • A: render
    B: render

  • 点击 【换车】 按钮,输出结果如下
  • A: render
    B: componentWillReceiveProps {carName: '奥拓'}
    B: shouldComponentUpdate
    B: componentWillUpdate
    B: render
    B: componentDidUpdate


    四、生命周期(新)

    1、基本介绍
  • 初始化阶段:由 ReactDOM.render() 触发初次渲染
  • 1. constructor()

    2. getDerivedStateFromProps()

    3. render():必须使用

    4. componentDidMount():常用,一般在这个钩子中做一些初始化的事,例如:发送网络请求、开启定

  • 更新阶段:由组件内部 this.setsate() 或父组件重新 render() 触发
  • 1. getDerivedStateFromProps()

    2. shouldComponentUpdate()

    3. render()

    4. getSnapshotBeforeUpdate()

    5. componentDidUpdate()

  • 卸载组件:由 ReactDOM.unmountComponentAtNode() 触发
  • 1. componentwillUnmount():常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

    2、演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>生命周期(新)</title>
    </head>

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

    <script src="../js/react17.0/react.development.js" type="text/javascript"></script>
    <script src="../js/react17.0/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react17.0/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
    class Count extends React.Component {

    // 构造器
    constructor(props) {
    console.log("Count: constructor");
    super(props);

    this.state = {
    count: 0,
    };
    }

    add = () => {
    let { count } = this.state;
    this.setState({
    count: count + 1,
    });
    };

    kill = () => {
    ReactDOM.unmountComponentAtNode(document.getElementById("test"));
    };

    force = () => {
    this.forceUpdate();
    };

    // 若 state 需要根据 props 的变化来更新
    static getDerivedStateFromProps(props, state) {
    console.log("Count: getDerivedStateFromProps", props, state);
    // return { count: 100 }; // 强制修改 state,无论什么情况,都把 count 设置为 100
    // return props; // 用 props 完全替换 state
    return null; // 返回 null 表示不更新 state
    }

    // 在更新之前获取快照
    getSnapshotBeforeUpdate() {
    console.log("Count: getSnapshotBeforeUpdate");
    return "hello";
    }

    // // 组件将要挂载的钩子
    // UNSAFE_componentWillMount() {
    // console.log("Count: componentWillMount");
    // }

    // 组件挂载完毕的钩子
    componentDidMount() {
    console.log("Count: componentDidMount");
    }

    // 组件将要卸载的钩子
    componentWillUnmount() {
    console.log("Count: componentWillUnmount");
    }

    // 控制组件更新的阀门
    shouldComponentUpdate() {
    console.log("Count: shouldComponentUpdate");
    return true;
    }

    // // 组件将要更新的钩子
    // UNSAFE_componentWillUpdate() {
    // console.log("Count: componentWillUpdate");
    // }

    // 组件更新完毕的钩子
    componentDidUpdate(preProps, preState, snapshotValue) {
    console.log("Count: componentDidUpdate", preProps, preState, snapshotValue);
    }

    render() {
    console.log("Count: render");
    return (
    <div>
    <h2>当前求和为:{this.state.count}</h2>
    <button onClick={this.add}>点我 + 1</button>
    <br />
    <button onClick={this.kill}>卸载组件</button>
    <br />
    <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
    </div>
    );
    }
    }

    ReactDOM.render(<Count name="tom" />, document.getElementById("test"));
    </script>
    </html>

  • 打开页面,输出结果如下
  • Count: constructor
    Count: getDerivedStateFromProps {name: 'tom'} {count: 0}
    Count: render
    Count: componentDidMount

  • 点击 【点我 + 1】 按钮,输出结果如下
  • Count: getDerivedStateFromProps {name: 'tom'} {count: 1}
    Count: shouldComponentUpdate
    Count: render
    Count: getSnapshotBeforeUpdate
    Count: componentDidUpdate {name: 'tom'} {count: 0} hello

  • 点击 【不更改任何状态中的数据,强制更新一下】,输出结果如下
  • Count: getDerivedStateFromProps {name: 'tom'} {count: 1}
    Count: render
    Count: getSnapshotBeforeUpdate
    Count: componentDidUpdate {name: 'tom'} {count: 1} hello

  • 点击 【卸载组件】 按钮,输出结果如下
  • Count: componentWillUnmount

    赞(0)
    未经允许不得转载:171主机测评 » React - 收集表单元素、收集表单元素优化、生命周期(旧)、生命周期(新)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址