React基础

1.Ref事件处理:
  • 通过onXxx属性指定事件处理函数(注意大小写)
    • React使用的是自定义(合成)事件,而不是使用的原生DOM事件-----为了更好的兼容性
    • 通过event.target得到发生事件的DOM元素对象------为了高效
  • 通过event.target得到发生事件的DOM元素对象---------不要过渡的使用ref
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>非受控组件</title>
</head>

<body>
    <div id="test"></div>
    <script src="../js/react.development.js"></script>
    <script src="../js/react-dom.development.js"></script>
    <script src="../js/babel.min.js"></script>
    <script src="../js/prop-types.js"></script>
    <script type="text/babel">
        //表单中输入类的Dom,如果是现用现取就属于非受控组件。如提交表单,现在获取数据,下面紧接着使用就属于现用现取
        class Login extends React.Component {
            handleSubmit = (event) => {
                event.preventDefault();//阻止表单的提交,即在表单提交的时候不进行默认的页面刷新
                const { username, password } = this
                alert(`你输入的用户名是${username.value},密码是${password.value}`)
            }
            render() {
                return (
                    <form action="" id='login' onSubmit={this.handleSubmit}>
                        用户名:<input ref={c => this.username = c} type="text" name='username' /><br />&nbsp;&nbsp;&nbsp;码:<input ref={c => this.password = c} type='password' name='password' /><br />
                        <button>登录</button>
                    </form>
                )
            }
        }
        ReactDOM.render(<Login />, document.getElementById("test"))
    </script>
</body>

</html>
5.受控组件(特点:相当于vue中的双向数据绑定)
<!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>受控组件</title>
</head>

<body>
    <div id="test"></div>
    <script src="../js/react.development.js"></script>
    <script src="../js/react-dom.development.js"></script>
    <script src="../js/babel.min.js"></script>
    <script src="../js/prop-types.js"></script>
    <script type="text/babel">
        //受控组件相当于vue里面的想象数据绑定,可以通过改变state里面值的内容而改变数据,也可以通过改变数据从而改变值的内容
        //表单中输入类的Dom,如果是现用现取就属于非受控组件。如提交表单,现在获取数据,下面紧接着使用就属于现用现取
        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();//阻止表单的提交,即在表单提交的时候不进行默认的页面刷新
                const {username,password}=this.state
                alert(`你输入的用户名是${username},密码是${password}`)
            }
            render() {
                return (
                    <form action="" id='login' onSubmit={this.handleSubmit}>
                        用户名:<input onChange={this.saveUsername} type="text" name='username' /><br />&nbsp;&nbsp;&nbsp;码:<input onChange={this.savePassword} type='password' name='password' /><br />
                        <button>登录</button>
                    </form>
                )
            }
        }
        ReactDOM.render(<Login />, document.getElementById("test"))
    </script>
</body>

</html>
6.高阶函数

什么是高阶函数?

如果一个函数符合规范中的任何一个,那该函数就是高阶函数。

  • 若A函数,接收的参数是一个函数,那么A就可以成为高阶函数

  • 若A函数,调用返回值依然是一个函数,那么A就可以成为高阶函数

    常见的高阶函数:Promise,setTimeout,arr,map()等等。

    例子如下所示:

<!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>高阶函数</title>
</head>

<body>
    <div id="test"></div>
    <script src="../js/react.development.js"></script>
    <script src="../js/react-dom.development.js"></script>
    <script src="../js/babel.min.js"></script>
    <script src="../js/prop-types.js"></script>
    <script type="text/babel">
        class Login extends React.Component {
            state = {
                username: "",//用户名
                password: ""//密码
            }
            saveFormData = (dataType) => {
                //event指的是操作的某个元素可以获取相关内容的所有东西
                return  (event)=>{
                console.log(dataType,event.target.value);
                }
            }
            handleSubmit = (event) => {
                event.preventDefault();//阻止表单的提交,即在表单提交的时候不进行默认的页面刷新
                const {username,password}=this.state
                alert(`你输入的用户名是${username},密码是${password}`)
            }
            render() {
                return (
                    <form action="" id='login' onSubmit={this.handleSubmit}>
                        用户名:<input onChange={this.saveFormData('username')} type="text" name='username' /><br />&nbsp;&nbsp;&nbsp;码:<input onChange={this.saveFormData('password')} type='password' name='password' /><br />
                        <button>登录</button>
                    </form>
                )
            }
        }
        ReactDOM.render(<Login />, document.getElementById("test"))
    </script>
</body>

</html>

函数柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后一次统一处理的编码形式。

7.组件的生命周期

a.初始生命周期

<!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>初始生命周期</title>
</head>

<body>
    <div id="test"></div>
    <script src="../../js/react.development.js"></script>
    <script src="../../js/react-dom.development.js"></script>
    <script src="../../js/prop-types.js"></script>
    <script src="../../js/babel.min.js"></script>
    <script type="text/babel">
        //生命周期回调函数<=>生命周期钩子函数<=>生命周期函数<=>生命周期钩子
        class Life extends React.Component {
            state = {
                opacity: 1
            }
            death = () => {
                // clearInterval(this.timer)
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            //组件挂载完毕之后使用
            componentDidMount() {
                this.timer = setInterval(() => {
                    let { opacity } = this.state
                    opacity -= 0.1
                    if (opacity <= 0) opacity = 1
                    this.setState({ opacity })
                }, 200)
            }
            //组件将要卸载
            componentWillUnmount() {
                clearInterval(this.timer)
            }
            //render调用时候:1.初始化渲染,2.状态更新之后
            render() {
                return (
                    <div>
                        <h2 style={{ opacity: this.state.opacity }}>React的生命周期</h2>
                        <button onClick={this.death}>React</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Life />, document.getElementById('test'))
    </script>
</body>

</html>

生命周期
b.生命周期组件挂载流程

<!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>生命周期钩子</title>
</head>

<body>
    <div id="test"></div>
    <script src="../../js/react.development.js"></script>
    <script src="../../js/react-dom.development.js"></script>
    <script src="../../js/prop-types.js"></script>
    <script src="../../js/babel.min.js"></script>
    <script type="text/babel">
        //创建组件
        class Count extends React.Component {
            //构造器
            constructor(props) {
                console.log('count-constructor');
                super(props)
                //初始化状态
                this.state = { count: 0 }
            }
            add = () => {
                //获取原状态
                const { count } = this.state;
                //更新状态
                this.setState({ count: count + 1 })
            }
            //卸载组件按钮的回调
            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            //组件将要挂载的钩子
            componentWillMount() {
                console.log('count-componentWillMount');
            }
            //组件挂载完毕的钩子
            componentDidMount() {
                console.log('count-componentDidMount');
            }
            //组件将要卸载的钩子
            componentWillUnmount() {
                console.log('count-componentWillUnmount');
            }
            render() {
                console.log('count-render');
                const { count } = this.state;
                return (
                    <div>
                        <h2>当前求和为{count}</h2>
                        <button onClick={this.add}>点我加一</button>
                        <button onClick={this.death}>点我卸载组件</button>
                    </div>
                )
            }
        }
        //渲染组件
        ReactDOM.render(<Count />, document.getElementById("test"))
    </script>
</body>

</html>

c.组件更新

方式一:setState更新流程

<!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>生命周期钩子</title>
</head>

<body>
    <div id="test"></div>
    <script src="../../js/react.development.js"></script>
    <script src="../../js/react-dom.development.js"></script>
    <script src="../../js/prop-types.js"></script>
    <script src="../../js/babel.min.js"></script>
    <script type="text/babel">
        //创建组件
        class Count extends React.Component {
            //构造器
            constructor(props) {
                console.log('count-constructor');
                super(props)
                //初始化状态
                this.state = { count: 0 }
            }
            add = () => {
                //获取原状态
                const { count } = this.state;
                //更新状态
                this.setState({ count: count + 1 })
            }
            //卸载组件按钮的回调
            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            //组件将要挂载的钩子
            componentWillMount() {
                console.log('count-componentWillMount');
            }
            //组件挂载完毕的钩子
            componentDidMount() {
                console.log('count-componentDidMount');
            }
            //组件将要卸载的钩子
            componentWillUnmount() {
                console.log('count-componentWillUnmount');
            }
            //控制组件更新的"阀门"
            shouldComponentUpdate() {
                //这个钩子的返回值为true或false,如果不写返回值虽然会输出'count-shouldComponentUptade'但是后面会报错,下面的操作无法执行。
                //如果返回值为true,阀门开启可以进行下一步的操作,进行数据的更新
                console.log('count-shouldComponentUptade');
                return true
            }
            //组件将要更新的钩子
            componentWillUpdate(){
                console.log('count-componentWillUpdate');
            }
            //组件更新完毕的钩子
            componentDidUpdate(){
                console.log('count-componentDidUpdate');
            }
            render() {
                console.log('count-render');
                const { count } = this.state;
                return (
                    <div>
                        <h2>当前求和为{count}</h2>
                        <button onClick={this.add}>点我加一</button>
                        <button onClick={this.death}>点我卸载组件</button>
                    </div>
                )
            }
        }
        //渲染组件
        ReactDOM.render(<Count />, document.getElementById("test"))
    </script>
</body>

</html>

方式二.forceUpdate():强制更新

<!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>生命周期钩子</title>
</head>

<body>
    <div id="test"></div>
    <script src="../../js/react.development.js"></script>
    <script src="../../js/react-dom.development.js"></script>
    <script src="../../js/prop-types.js"></script>
    <script src="../../js/babel.min.js"></script>
    <script type="text/babel">
        //创建组件
        class Count extends React.Component {
            //构造器
            constructor(props) {
                console.log('count-constructor');
                super(props)
                //初始化状态
                this.state = { count: 0 }
            }
            add = () => {
                //获取原状态
                const { count } = this.state;
                //更新状态
                this.setState({ count: count + 1 })
            }
            //卸载组件按钮的回调
            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            //强制更新组件按钮的回调------与正常操作相比:忽略阀门的控制,直接进行后续的操作
            force = () => {
                console.log('强制更新', this);
                this.forceUpdate()
            }
            //组件将要挂载的钩子
            componentWillMount() {
                console.log('count-componentWillMount');
            }
            //组件挂载完毕的钩子
            componentDidMount() {
                console.log('count-componentDidMount');
            }
            //组件将要卸载的钩子
            componentWillUnmount() {
                console.log('count-componentWillUnmount');
            }
            //控制组件更新的"阀门"
            shouldComponentUpdate() {
                //这个钩子的返回值为true或false,如果不写返回值虽然会输出'count-shouldComponentUptade'但是后面会报错,下面的操作无法执行。
                //如果返回值为true,阀门开启可以进行下一步的操作,进行数据的更新
                console.log('count-shouldComponentUptade');
                return true
            }
            //组件将要更新的钩子
            componentWillUpdate() {
                console.log('count-componentWillUpdate');
            }
            //组件更新完毕的钩子
            componentDidUpdate() {
                console.log('count-componentDidUpdate');
            }
            render() {
                console.log('count-render');
                const { count } = this.state;
                return (
                    <div>
                        <h2>当前求和为{count}</h2>
                        <button onClick={this.add}>点我加一</button>
                        <button onClick={this.death}>点我卸载组件</button>
                        <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
                    </div>
                )
            }
        }
        //渲染组件
        ReactDOM.render(<Count />, document.getElementById("test"))
    </script>
</body>

</html>

方式三:父组件render流向

<!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>生命周期父组件render流向</title>
</head>

<body>
    <div id="test"></div>
    <script src="../../js/react.development.js"></script>
    <script src="../../js/react-dom.development.js"></script>
    <script src="../../js/prop-types.js"></script>
    <script src="../../js/babel.min.js"></script>
    <script type="text/babel">
        class A extends React.Component {
            //初始化状态
            state = { carName: '奔驰' }
            changeCar = () => {
                this.setState({ carName: "奥拓" })
            }
            render() {
                return (
                    <div>
                        <div>A</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName} />
                    </div>

                )
            }
        }
        class B extends React.Component {
            //组件将要接收新的props的钩子
            //该狗子第一次接收到参数不算,从第二次接收才开始执行此钩子
            componentWillReceiveProps(props) {
                console.log('B-----componentWillReactiveProps', props);
            }
            //控制组件更新的"阀门"
            shouldComponentUpdate() {
                //这个钩子的返回值为true或false,如果不写返回值虽然会输出'count-shouldComponentUptade'但是后面会报错,下面的操作无法执行。
                //如果返回值为true,阀门开启可以进行下一步的操作,进行数据的更新
                console.log('B-shouldComponentUptade');
                return true
            }
            //组件将要更新的钩子
            componentWillUpdate() {
                console.log('B-componentWillUpdate');
            }
            //组件更新完毕的钩子
            componentDidUpdate() {
                console.log('B-componentDidUpdate');
            }
            render() {
                return (
                    <div>B,接受到的车是:{this.props.carName}</div>
                )
            }
        }
        ReactDOM.render(<A />, document.getElementById("test"))
    </script>
</body>

</html>

总结:

​ 1. 初始化阶段: 由ReactDOM.render()触发—初次渲染

​ 1. constructor()

​ 2. componentWillMount()

​ 3. render()

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

​ 2. 更新阶段: 由组件内部this.setState()或父组件render触发

​ 1. shouldComponentUpdate()

​ 2. componentWillUpdate()

​ 3. render() ----------是必须使用的一个

​ 4. componentDidUpdate()

​ 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发

​ 1. componentWillUnmount() ====> 常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

新旧生命周期对比

左边是旧的生命周期,右边是新的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vdnUXH5Y-1681607678919)(C:\Users\86157\AppData\Roaming\Typora\typora-user-images\image-20230414163146469.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KAIAEsz3-1681607678919)(C:\Users\86157\AppData\Roaming\Typora\typora-user-images\image-20230414163536767.png)]

总结:新旧生命周期对比,即将废弃三个钩子并且提出了两个新的钩子。
()或父组件render触发

​ 1. shouldComponentUpdate()

​ 2. componentWillUpdate()

​ 3. render() ----------是必须使用的一个

​ 4. componentDidUpdate()

​ 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发

​ 1. componentWillUnmount() ====> 常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

新旧生命周期对比

左边是旧的生命周期,右边是新的生命周期
在这里插入图片描述
在这里插入图片描述
总结:新旧生命周期对比,即将废弃三个钩子并且提出了两个新的钩子。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值