B5net

人生是场无尽旅途,欢声笑语,踟蹰彷徨,走过的是岁月,路过的是迷茫。向前,是希望极光;回首,是悠长深巷。

【React学习笔记】脚本方式使用react

Published on:2022-04-25

一、基本使用


1.类似原生写法

<script src=”xxx 引入react的运行js”></script>
<div id="root"></div> //定义一个根节点
<script>
    //React类 负责创建元素
    //ReactDom类 负责渲染元素到其他元素中

    let now = new Date().toLocaleTimeString();
    //1.创建元素 React.createElement
    //第一个参数 h3 为html标签名
    //第二个参数 为元素属性
    //第三个参数 元素内容

    let element = React.createElement('h3', { id: 'time', className: 'danger' }, '当前时间:' + now);
    //2.ReactDom 渲染元素到id = "root"的标签内
    //第一个参数为 元素
    //第二个为id

    ReactDOM.render(element, root);
</script>
在浏览器运行html文件 就会出现 <h3 class=”danger” id=”time”>当前时间:xxx</h3>

2.jsx写法

规范:

  定义虚拟dom时,不用引号;

  标签中混入js表达式使用{};

  样式的类名使用className和js的createElement一致;

  内联样式style 使用 {{}} 双括号。

  不能有多个根标签,且每个标签必须闭合。

  标签首字母小写,转为同名html标签;首字母大写代表为组件


<!-- 引入babel用来将jsx代码转为浏览器可执行的代码 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- type="text/babel" 用来告诉babel 该标签里面的代码需要转换 -->
<script type="text/babel">
    //React 使用 JSX 来替代常规的 JavaScript。在js文件中书写xml格式的dom操作代码
    //JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。
    //JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
    //它是类型安全的,在编译过程中就能发现错误。
    //使用 JSX 编写模板更加简单快速。

    let now = new Date().toLocaleTimeString();
    let element = <h3 className="danger" id="time">当前时间:{now}</h3>
    ReactDOM.render(element, root)
</script>

二、组件的使用


组件的方法首字母必须大写

返回值为jsx代码

函数里面的thisundefined,因为bable编译中开启严格模式,禁止函数中的this指向windows

组件三大属性 props,state,refs


1.函数方式组件

<script type="text/babel">
    //组件,函数名要求大驼峰 否则作为普通函数使用
    //返回jsx代码

    function TestComponent() {
        return <h1>Hello World!</h1>
    }
    //原生函数调用方式
    ReactDOM.render(TestComponent(), root)
    //语法糖 <TestComponent/>
    ReactDOM.render(<TestComponent />, root)
        
    //复用性和组合
//可以创建多个组件进行输出

let name = "adads";
    const element = <div>
        {name}
        <TestComponent />
        <TestComponent />
    </div>
    ReactDOM.render(element, root)
</script>

2.类方式组件

<script type="text/babel">
        //类方式组件,类名也是大驼峰方式
        //必须继承父类 React.Component

        class HelloWorld extends React.Component {
            //一个固定的方法,必须存在
            render() {
                return <h1>Hello World</h1>
            }
        }
        // 原生调用方法
        ReactDOM.render(new HelloWorld().render(), root)
        //语法糖方式
        ReactDOM.render(<HelloWorld />, root)
</script>

3.组件传值

<script type="text/babel">
        //1.函数组件传值
        function TestName(props) {
            return <h1>Hello {props.name}</h1>
        }
        //原生方式传值
        ReactDOM.render(TestName({ name: '张三' }), user_name)
        //语法糖方式
        ReactDOM.render(<TestName name="王五" />, user_name)
        //2.类组件传值
        class TestAge extends React.Component {
            // 有一个类似的构造方法在父类中
            // constructor(props) {
            //     this.props = props
            // }

            render(props) {
                return <h2>年龄: {this.props.age}</h2>
            }
        }
        //原生方式传值
        ReactDOM.render(new TestAge({ age: 18 }).render(), user_age)
        //语法糖方式
        ReactDOM.render(<TestAge age="19" />, user_age)
</script>

对props进行验证和默认值

        //限制props的类型和验证
        //需要引入一个prop-types的js
        TestAge.propTypes = {
             name: PropTypes.string,
             age:PropTypes.number.isRequired        
        }
        //设置props默认值
        TestAge.defaultProps = {
            name: '姓名'
        }
对于类可以写进类中,定义为静态
class TestAge extends React.Component {
            static defaultProps = {
                name: '姓名'
            }
            static propTypes = {
                name: PropTypes.string,
                age: PropTypes.number.isRequired
            }

三、事件的调用

事件的方法为onClick,on+事件名称首字母大写

<script type="text/babel">
        //1. 函数写法
        // 事件触发使用 onClick  
        // 事件名使用 {方法名}  注意不要带有()

        function TestEvent() {
            return <div><button onClick={show}>点击事件</button></div>
        }
        function show() {
            alert('函数点击事件触发了')
        }
        ReactDOM.render(<TestEvent />, root)
        //2.类的形式
        class Demo extends React.Component {
            name = "点击"
            //事件方法
            show() {
                alert('函数点击事件触发了')
            }
            // 普通函数方法如果方法内使用this调用类中的属性或方法,需要面临this指向问题
            show1() {
                //当前方法为普通方法,this为 谁触发的就代表是谁
                //直接使用this.name, this代表了window,是无法读取name的
                //需要将点击事件 this.show改为 this.show.bind(this)将当前触发的对象改为当前类
                // 还可以使用箭头函数来触发点击方法 ()=>this.show()
                alert('类点击事件1触发了' + this.name)

            }
            //将事件改为箭头函数,则会规避上面show1方法中的this的绑定问题
            show1 = () => {
                alert('类点击事件2触发了' + this.name)
            }
            render() {
                //{this.show}为当前类的show,{show} 为类外的全局方法show
                return <div>
                    <button onClick={this.show}>点击事件0</button>
                    <button onClick={this.show1.bind(this)}>点击事件1</button>
                    <button onClick={() => this.show1()}>点击事件2</button>
                    <button onClick={this.show1}>点击事件3</button>
                </div >
            }
        }
        ReactDOM.render(<Demo />, root)
</script>

四、state,数据更改后,页面也进行更改


<script type="text/babel">
        //数据修改后,页面上的显示也会同步修改
        //state 状态值  只有class方式创建的组件可以使用

        class Demo extends React.Component {
            count = 1;
            //事件方法
            //通过点击后 发现页面上的h3值不会方法改变

            _doAdd = () => {
                this.count++
                // console.log(this.count)
            }
            //react提供的state属性
            state = { count: 1 };
            _doAdd1 = () => {
                //使用setState,修改数据,更新ui,是异步操作
                //有一个参数二的回调方法,

                this.setState({ count: this.state.count + 1 })
                // this.setState({ count: this.state.count + 1 }, () => {
                //     console.log(this.state.count)
                // })

            }
            render() {
                return <div>
                    <h3>{this.count}</h3>
                    <button onClick={this._doAdd}>点击增加</button>
                    <h3>{this.state.count}</h3>
                    <button onClick={this._doAdd1}>点击增加state</button>
                </div>
            }
        }
        ReactDOM.render(<Demo />, root)
</script>

五、Refs


<script type="text/babel">
        class Demo extends React.Component {
            // 1. 字符串类型的ref,不推荐
            showData = () => {
                const { left_input } = this.refs
                //两种写法
                // this.refs.left_input.value
                // this.refs['left_input'].value
                console.log(left_input.value)
            }
            // render() {
            //     return <div>
            //         <input type="text" ref="left_input" />
            //         <button onClick={this.showData}>点击显示</button>
            //     </div>
            // }

            //2.回调方式的ref,ref中定义一个匿名函数或者调用一个已存在的函数,不推荐
            showData2 = () => {
                console.log(this.input1.value)
            }
            inputBind = (node) => {
                this.input1 = node
            }
            // render() {
            //     return <div>
            //         <input type="text" ref={(a) => this.input1 = a} />
            //         <input type="text" ref={this.inputBind} />
            //         <button onClick={this.showData2}>点击显示</button
            //     </div>
            // }

            //3.createRef 形式使用,推荐方式
            showData3 = () => {
                //返回一个current键的对象
                console.log(this.myRef)
                console.log(this.myRef.current.value)
            }
            //创建一个ref容器,只能使用一次,多个创建多个
            myRef = React.createRef()
            render() {
                return <div>
                    <input type="text" ref={this.myRef} />
                    <button onClick={this.showData3}>点击显示</button>
                </div>
            }
        }
        ReactDOM.render(<Demo />, document.getElementById('root'))
</script>

六、生命周期(旧)


react的js版本小于17时
1.首次初始化时
       constructor->componentWillMount->render->componentDidMount
2.setState更新时
      shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate
3.通过forceUpdate强制更新时
     componentWillUpdate->render->componentDidUpdate
4.作为子组件props更改时
       componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate

  class Demo extends React.Component {
            //一、首次初始化组件时
            //1、组件初始化
            constructor(props) {
                super(props)
                this.state = { opacity: 1 }
                console.log('1.组件初始化')
            }
            //2、组件挂载前调用,1次
            componentWillMount() {
                console.log('2.组件挂载前:WillMount')
            }
            //3、初始化渲染和状态更新时调用 1+n次
            render() {
                console.log('3.渲染:render')
                return <div>
                    <h2 style={{ opacity: this.state.opacity }}>你好,开始你得表演</h2>
                    <button onClick={this.death}>卸载</button>
                    <button onClick={this.forceData}>强制更新</button>
                </div>
            }
            //4、组件完成挂载后调用,1次
            componentDidMount() {
                console.log('4.组件挂载:DidMount')
                this.timer = setTimeout(() => {
                    let opacity = this.state.opacity - 0.1
                    opacity = opacity <= 0 ? 1 : opacity
                    this.setState({ opacity })
                }, 200)
            }

            //二、组件更新周期
            //1.state更新时根据新的props/state决定是否重新渲染
            shouldComponentUpdate(nextProps, nextState) {
                console.log("1,是否更新");
                return true;
            }
            //2.更新渲染前的操作
            componentWillUpdate(nextProps, nextState) {
                console.log("2,更新渲染前");
            }
            //3.render渲染
            //4.更新渲染完成后,参数为旧的state
            componentDidUpdate(preProps, preState) {
                console.log("4,渲染完成后");
            }

            //三、强制更新时生命周期
            //调用forceUpdate()强制更新的生命周期
            forceData = () => {
                this.forceUpdate()
            }
            //生命周期为 componentWillUpdate->render->componentDidUpdate

            //四、作为子组件时,更新组件的props时,会走组件更新生命周期,但是多一个componentWillReceiveProps
            //将要接受修改的修属性
            componentWillReceiveProps(nextProps, nextState) {
                console.log('0,接受props')
            }
            death = () => {
                //手动卸载
                ReactDOM.unmountComponentAtNode(root)
            }
            //组件卸载前,执行一些定时器等,防止内存溢出
            componentWillUnmount() {
                console.log('卸载前')
                clearInterval(this.timer)
            }
        }

在新版本中 废弃三个带有will除了卸载前的,挂载前,更新前,props componentWillMountcomponentWillUpdatecomponentWillReceiveProps

需要在前面增加 UNSAFE_

 

新增了一个 getDerivedStateFromProps constructor之后执行,以及组件更新第一步执行

还有一个 getSnapshotBeforeUpdate 在组件更新时的render之后执行

留言列表(0)

    留言

    B5net

    人生是场无尽旅途,欢声笑语,踟蹰彷徨,走过的是岁月,路过的是迷茫。向前,是希望极光;回首,是悠长深巷。

    开源项目
    最新评论
    小白 :大佬您好 请问一下 http://b5laravelcmf.b5net.com/admin这个演示网址的全部代码有吗,gitee上不全呢,还能提供一下吗,感激不尽阿
    tz :大佬 B5YiiCMF 还开放吗
    weifox on GoLang常用的三方库 :还有 https://github.com/golang-module/carbon
    php :关于导出功能:1、B5thinkCMF部署后 参数的导出功能点击后就白屏了,不知道是哪里有问题?2、人员部门的导出功能没看懂怎么配置的? 只是启用exportshow=true吗 方便的话请答复下,谢谢!
    初学者 :您好! 部署了您的B5ThinkCMF,请教下 使用新增功能如何实现二级联动呢 ?谢谢
    11 :22
    pcy :前排围观
    Louis :冰舞的博客使用yii框架做的吧,B5ThinkCMF在本地部署后,登录系统的响应时间要比B5YiiCMF的登录时间长,还有一些Bug待修复
    34 :感谢你的开源项目
    文章分类