ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

React学习笔记(二)

2022-02-02 23:30:00  阅读:146  来源: 互联网

标签:学习 console render 笔记 React nbsp 组件 event


组件实例的三大属性

1.属性一

state
【概念】React 把组件看成是一个状态机。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
【注意】

  1. 组件中render方法中的this为组件实例对象
  2. 组件自定义的方法中this为undefined,如何解决?
    a. 强制绑定this:通过函数对象的bind()
    b. 箭头函数
  3. 状态数据,不能直接修改或更新
  4. 不要直接修改State,而是使用setState()

2.属性二

props
子组件只能通过 props 来传递数据

	<script type="text/babel">
        //1.创建组件
        class Person extends React.Component {
            render() {
                const {name,age} = this.props;
                return (
                    <div>
                        <ul>
                            <li>姓名:{name}</li>
                            <li>年龄:{age}</li>
                        </ul>
                    </div>
                )
            }
        }
        
        //对标签属性进行类型|必要性的限制(这里需要引入PropTypes的React库文件)
        Person.propTypes = {
            name: PropTypes.string.isRequired,
            sex: PropTypes.string,
            age: PropTypes.number,
            speak: PropTypes.func
        }
        //对标签属性进行类型、必要性的限制
        Person.defultProps = {
            sex:'女',
            age:18
        }

        //2.渲染组件到页面
        ReactDOM.render(<Person name="张三" age="14"/>, document.getElementById('test1'));
        ReactDOM.render(<Person name="老王" age="18"/>, document.getElementById('test2'));
    
        function speak(){
            console.log('我说话了');
        }
    </script>

props简写方式(把所有的限制放在类的里边)

	<script type="text/babel">
	    //1.创建组件
	    class Person extends React.Component {
	        //对标签属性进行类型|必要性的限制
	       static propTypes = {
	            name: PropTypes.string.isRequired,
	            sex: PropTypes.string,
	            age: PropTypes.number,
	            speak: PropTypes.func
	        }
	        //对标签属性进行类型、必要性的限制
	        static defultProps = {
	            sex:'女',
	            age:18
	        }
	        render() {
	            const {name,age} = this.props;
	            return (
	                <div>
	                    <ul>
	                        <li>姓名:{name}</li>
	                        <li>年龄:{age}</li>
	                    </ul>
	                </div>
	            )
	        }
	    }
	
	    //2.渲染组件到页面
	    ReactDOM.render(<Person name="张三" age="14"/>, document.getElementById('test'));
	    
	    function speak(){
	        console.log('我说话了');
	    }
	</script>

3.属性三

ref
ref是React提供的用来操纵React组件实例或者DOM元素的接口。

ref的三种方式

  1. 字符串形式的ref
	 <script type="text/babel">
        //1.创建组件
        class Demo extends React.Component {
            showIputDate = () => {
                const {input2} = this.refs;
                alert(input2.value);
            }
            render() {
                return (    
                    <div>
                        <input onBlur={this.showIputDate} ref="input2" type="text" placeholder="失去焦点获取内容" />&nbsp;&nbsp;
                    </div>
                )
            }
        }

        //2.渲染组件到页面
        ReactDOM.render(<Demo/>, document.getElementById('test'));
    </script>
  1. 回调形式的ref
	 <script type="text/babel">
        //1.创建组件
        class Demo extends React.Component {
            showDate = () => {
                const {input} = this;
                alert(input.value);
            }

            showIputDate2 = () => {
                const {input3} = this;
                alert(input3.value);
            }

            render() {
                return (    
                    <div>
                        <input type="text" ref={(e)=>{this.input=e;console.log("@",e)}} placeholder="点击按钮获取内容" /> &nbsp;&nbsp;
                        <button onClick={this.showDate}>按钮</button>&nbsp;&nbsp;
                        <input onBlur={this.showIputDate2} ref={(c) => {this.input3 = c}} type="text" placeholder="失去焦点获取内容" />
                    </div>
                )
            }
        }

        //2.渲染组件到页面
        ReactDOM.render(<Demo/>, document.getElementById('test'));
    </script>
  1. ceateRef的使用
	<script type="text/babel">
	  //1.创建组件
        class Demo extends React.Component {
            /*
                React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点
            */
            myRef = React.createRef();
            myRef2 = React.createRef();
            showDate = () =>{
                alert(this.myRef.current.value);
            }
             
            showIputDate2 = () =>{
                alert(this.myRef2.current.value);
            }
            render() {
                return (    
                    <div>   
                        <input type="text" ref={this.myRef} placeholder="点击按钮提示数据" />&nbsp;&nbsp;
                        <button onClick={this.showDate}>按钮</button>&nbsp;&nbsp;
                        <input onBlur={this.showIputDate2} ref={this.myRef2} type="text" placeholder="失去焦点获取内容" />&nbsp;&nbsp;
                    </div>
                )
            }
        }

        //2.渲染组件到页面
        ReactDOM.render(<Demo/>, document.getElementById('test'));
  </script>

【强调】勿过度使用refs

非受控组件与受控组件

非受控组件

	<script type="text/babel">
        class Login extends React.Component{
            onLogin = (event) => {
                //阻止表单提交
                event.preventDefault();
                const {username,password} = this;
                alert(`你输入的用户名是${username.value},密码是${password.value}`)
            }
            render() {
                return (
                    <form action="https://baidu.com" onSubmit={this.onLogin}>
                        用户名: <input ref={c => this.username=c} type="text" name="username"/> &nbsp;
                        密码:<input ref={c => this.password=c} type="text" name="password"/>&nbsp;
                        <button>提交</button>
                    </form>
                )
            }
        }

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

受控组件

	<script type="text/babel">
       class Login extends React.Component{
            // 获取用户名到state
            changeUsername = (event) => {
                this.setState({username:event.target.value});
            }
            // 获取密码到state
            changePassword = (event) => {
                this.setState({password:event.target.value});
            }
            onLogin = (event) => {
                //阻止表单提交
                event.preventDefault();
                const {username,password} = this.state;
                alert(`你输入的用户名是${username},密码是${password}`)
            }
            render() {
                return (
                    <form action="https://baidu.com" onSubmit={this.onLogin}>
                        用户名: <input onChange={this.changeUsername} type="text" name="username"/> &nbsp;
                        密码:<input onChange={this.changePassword} type="text" name="password"/>&nbsp;
                        <button>提交</button>
                    </form>
                )
            }
            
        }

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

概念
高阶函数与函数的柯里化

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

  1. 若A函数,接受的参数是一个函数,那么A就是可以称之为高阶函数。
  2. 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。
    a.常见的高阶函数有:PromisesetTimeoutarr.map()等等

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

例子

		class Login extends React.Component{
            // 初始化状态
            state = {
                username:'', //用户名
                password: '' // 密码
            }
            // 获取表单数据到状态中
            saveFromDate = (typeDate) => {
                return(event)=>{
                    this.setState({[typeDate]:event.target.value});
                }
            }
            onSubmit = (event) => {
                //阻止表单提交
                event.preventDefault();
                const {username,password} = this.state;
                alert(`你输入的用户名是${username},密码是${password}`)
            }
            render() {
                return (
                    <form action="https://baidu.com" onSubmit={this.onSubmit}>
                        用户名: <input onChange={this.saveFromDate('username')} type="text" name="username"/> &nbsp;
                        密码:<input onChange={this.saveFromDate('password')} type="text" name="password"/>&nbsp;
                        <button>提交</button>
                    </form>
                )
            }
        }

        ReactDOM.render(<Login/>,document.getElementById('test'));

不用函数的柯里化实现

	、<script type="text/babel">
        class Login extends React.Component{
            // 初始化状态
            state = {
                username:'', //用户名
                password: '' // 密码
            }
            // 获取表单数据到状态中
            saveFromDate = (typeDate,event) => {
               this.setState({[typeDate]:event.target.value});
            }
            onSubmit = (event) => {
                //阻止表单提交
                event.preventDefault();
                const {username,password} = this.state;
                alert(`你输入的用户名是${username},密码是${password}`)
            }
            render() {
                return (
                    <form action="https://baidu.com" onSubmit={this.onSubmit}>
                        用户名: <input onChange={event => this.saveFromDate('username',event)} type="text" name="username"/> &nbsp;
                        密码:<input onChange={event => this.saveFromDate('password',event)} type="text" name="password"/>&nbsp;
                        <button>提交</button>
                    </form>
                )
            }
            
        }

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

react生命周期(旧与新)

  1. 组件从创建到死亡它会经历一些特定的阶段
  2. React组件中包含一系列钩子函数的生命周期,会在特定的时刻调用
  3. 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作

生命周期(旧)
在这里插入图片描述

  1. 初始化阶段:由ReactDOM.render()触发—初次渲染
    1)constructor()
    2) componentWillMount()
    3) render()
    4) componentDidMount() ====> 常用
    一般在这个钩子中做一些初始化的事,例如:开启定时器、 送网络请求、订阅消息
  2. 更新阶段:由组件内部this.setSate()或父组件render触发
    1) shouldComponentUpdate()
    2) componentWillUddate()
    3) render() ====> 必须使用的一个
    4)componentDidUpdate()
  3. 卸载组件:由ReactDOM.unmountComponentAtNode()触发
    1) componentWillUnmount() ====> 常用
    一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

例子

	<script type="text/babel">
        //创建组件
        class Sum extends React.Component{
            //构造器
            constructor(props){
                console.log('count---constructor');
                super(props)
                // 初始化状态
                this.state = {count:0};
            }

            //加1按钮的回调
            add = ()=>{
                //获取原状态
                let {count} = this.state;
                //更新状态
                this.setState({count:count+1})
            }

            //卸载组件按钮的回调
            death = ()=>{
                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>&nbsp;
                        <button onClick={this.death}>卸载</button>&nbsp;
                        <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
                    </div>
                )
            }
            
        }

        //父组件A
        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>
                )
            }
        }
        
        //子组件B
        class B extends React.Component{
            //组件将要接受新的props的钩子
            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>我是B组件,接受到的车:{this.props.carName}</div>
                )
            }
        }

        //渲染组件
        ReactDOM.render(<A/>,document.getElementById('test'));
        // ReactDOM.render(<Sum/>,document.getElementById('test'));
    </script>

生命周期(新)
在这里插入图片描述

生命周期新与旧版本的区别:

  1. 新版本即将废弃三个生命钩子:componentWillUnmount、componentWillUpdate和componentWillReceiveProps
  2. 提出2个新的生命钩子:getDerivedStateFromProps和getSnapshotBeforeUpdate

标签:学习,console,render,笔记,React,nbsp,组件,event
来源: https://blog.csdn.net/C_jiayouya/article/details/122762185

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有