IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React 面向组件开发 -> 正文阅读

[JavaScript知识库]React 面向组件开发

面向组件编程

函数式组件

普通的

<script type="text/babel">
    // 1、定义函数式组件
    function MyComponent(){
        return <h1>函数式组件的入门案例~</h1>;
    }

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

注意 :组件的名称首字母必须大写

在这里插入图片描述

带参数的

<script type="text/babel">
    function GetDate(param){
        return <h2>{param.data.toLocaleTimeString()}</h2>;
    }
    ReactDOM.render(<GetDate data={new Date()} />,document.getElementById("test"));
</script>

在这里插入图片描述

类式组件

复习类

<script>
    // 定义一个 Person 类
    class Person{
        // 定义构造器方法
        constructor(name,age){
            this.name=name;
            this.age = age;
        }
        // 定义一般方法,供实例使用
        speak(){
            console.log(`我叫${this.name},今年${this.age}`);
        }
    }

    // 创建一个实例对象
    const p1 = new Person('Tom',15);
    const p2 = new Person('jack',21);
    console.log(p1);
    console.log(p2);
    p1.speak();
    p2.speak();


    // 创建Student 类,继承 Person 类
    class Student extends Person{
        constructor(name,age,grade){
            super(name,age);// 声明了构造器,必须调用 super() 方法
            this.grade = grade;
        }
        
        // 重写父类的方法
        speak(){
            console.log(`我叫${this.name},今年${this.age}岁,在读${this.grade}年级`);
        }
    }

    const s1 = new Student('张三',21,'大一');
    console.log(s1);
    s1.speak();
</script>

在这里插入图片描述

类式组件应用

<script type="text/babel">
    // 创建一个类式组件,必须继承 React.Component 类
    class MyClassComponent extends React.Component{
        // render 必须是写的,必须有返回值
        render(){
            return <h1>类式组件入门案例</h1>;
        }
    }
    // 渲染组件到页面
    ReactDOM.render(<MyClassComponent />,document.getElementById("test"));
</script>

在这里插入图片描述

组件的分类

如果组件中有 状态 state 就是复杂组件,没有则是简单组件。

组件的实例的三大属性

  • state
  • props
  • refs

函数组件没有实例,类式组件有实例

stat

注意 :

1、组件自定义的方法中 this 为 undefined,如何解决?

  • 强制绑定this: 在构造器中通过函数对象的bind()

  • 箭头函数

2、状态数据,不能直接修改或更新。需要通过 setState 方式去更新state 中的值。

<script type="text/babel">
    // 创建组件
    class Weather extends React.Component {
        // 创建构造器
        constructor(props){
            super(props)
            this.state = {isHot:true}
            // 解决 类方法中 this 丢失问题
            this.changeWeather = this.changeWeather.bind(this)
        }
        render(){
            return <h2 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '寒冷'}</h2>
        }
        changeWeather(){
            // 类中的方法默认开了局部严格模式,所以 this 会丢失,this 的值为 undefined
            // 解决办法 :在构造器中加一行代码 :this.changeHot = this.changeHot.bind(this) 就会将方法挂在示例自身上
            //this.state.isHost = !this.state.isHot
            // 状态(state)中的值不可以直接更改,上面是直接更改,需要通过一个内置的API去修改(setState)
            const {isHot} = this.state;
            this.setState({isHot:!isHot});
        }
    }
    // 渲染到页面
    ReactDOM.render(<Weather/>,document.getElementById("test"))
</script>

构造器中东西简写(推荐这样写)

以后类中的自定义方法都使用 : 赋值语句+箭头函数

<script type="text/babel">
    class Weather extends React.Component {
        state = {isHost : true}
        render(){
            return <h2 onClick={this.changeHot}>今天天气很{this.state.isHost ? '炎热':'寒冷'}</h2>;
        }
        // 普通函数还是会发生this丢失,这里只能使用 箭头函数才可以保证this不丢失
        changeHot = () => {
            const {isHost} = this.state;
            this.setState({isHost:!isHost})
        }
    }
    ReactDOM.render(<Weather />,document.getElementById("test"))
</script>

props

简单应用

注意 :props 是只读的,在组件内部不允许修改 props 里的值

需求 :

  • 姓名必须指定,且为字符串
  • 性别为字符串类型,如果性别没有指定,默认是男
  • 年龄为数字类型,默认是18
<!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>Document</title>
    <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>
</head>
<body>
    <div id="test"></div>
    <div id="test2"></div>
    <script type="text/babel">
        // 加载类组件
        class Person extends React.Component{
            render(){
                // props 是只读的
                // this.props.name = "test" // 此行代码会报错,因为 props 是只读的
                return (
                    <ul>
                        <li>姓名 : {this.props.name}</li>
                        <li>年龄 : {this.props.age}</li>
                        <li>性别 : {this.props.sex}</li>
                    </ul>
                );
            }
        }
        // 对类式组件中所需要的属性做限制,这个时候需要新引入一个 js 文件../js/prop-types.js
        Person.propTypes = {
            name : PropTypes.string.isRequired, //名字非空且为字符串
            sex : PropTypes.string, // 性别必须是字符串
            age : PropTypes.number, // 年龄为数字类型
            speak : PropTypes.func // 限制 speak 为函数
        }
        // 指定类式组件中属性默认值
        Person.defaultProps = {
            sex : "男",
            age : 18
        }
        // <Person name="tom" age="21" sex="男"/> 这样参数是直接存放到 props 组件中
        ReactDOM.render(<Person name="tom" age={21} sex="男" speak={speak}/>,document.getElementById("test"))
        // 也可以封装成一个对象直接传参
        const p ={name:"tom",age:21,sex:"男"};
        // ...p 为展开对象,是babel和react的功能。与js 中的 {...p} 不是一回事
        ReactDOM.render(<Person {...p}/>,document.getElementById("test2"))

        function speak(){
            console.log("speak");
        }
    </script>
</body>
</html>

简写方式(将属性的限制和默认值放入类中)(推荐这样写)

<script type="text/babel">
    // 加载类组件
    class Person extends React.Component{
        // 对类式组件中所需要的属性做限制,这个时候需要新引入一个 js 文件../js/prop-types.js
        propTypes = {
            name : PropTypes.string.isRequired, //名字非空且为字符串
            sex : PropTypes.string, // 性别必须是字符串
            age : PropTypes.number, // 年龄为数字类型
            speak : PropTypes.func // 限制 speak 为函数
        }
        // 指定类式组件中属性默认值
        defaultProps = {
            sex : "男",
            age : 18
        }
        render(){
            return (
                <ul>
                    <li>姓名 : {this.props.name}</li>
                    <li>年龄 : {this.props.age}</li>
                    <li>性别 : {this.props.sex}</li>
                </ul>
            );
        }
    }
    const p ={name:"tom",age:21,sex:"男"};
    ReactDOM.render(<Person {...p}/>,document.getElementById("test2"))
</script>

函数式组件使用 props

<script type="text/babel">
    // 加载类组件
    function Person(props) {
        console.log(props);
        return (
            <ul>
                <li>姓名 : {props.name}</li>
                <li>年龄 : {props.age}</li>
                <li>性别 : {props.sex}</li>
            </ul>
        );
    }
    // 限制和默认值,在函数式组件也可以使用
    Person.propTypes = {
        name : PropTypes.string.isRequired, //名字非空且为字符串
            sex : PropTypes.string, // 性别必须是字符串
                age : PropTypes.number, // 年龄为数字类型
                    speak : PropTypes.func // 限制 speak 为函数
    }
    Person.defaultProps = {
        sex : "男",
            age : 18
    }
    const p ={name:"tom",age:21,sex:"男"};
    ReactDOM.render(<Person {...p} />, document.getElementById("test"))
</script>

refs

案例为 :提示在文本中输入的值(两种方式 :点击按钮提示、失去焦点提示)

分类 :

  • 字符串形式 refs
  • 回调函数形式 refs (用的最多的)
  • 官方 API :createRef (react 最推荐的)

字符串形式

不久将来将要废弃

<script type="text/babel">
    class Demo extends React.Component {
        render() {
            return (
                <div>
                    <input type="text" ref="input1" placeholder="点击按钮提示数据" /> &nbsp;
                    <button onClick={this.showData}>点击提取左侧数据</button>&nbsp;
                    <input onBlur={this.showData2} ref="input2" type="text" placeholder="失去焦点提示数据" />
                </div>
            )
        }
        showData = () => {
            // 拿到 dom 节点
            const input1 = this.refs.input1;
            // 获取值
            const value = input1.value;
            alert(value)
        }
        showData2 = () => {
            // 拿到 dom 节点
            const input2 = this.refs.input2;
            // 获取值
            const value = input2.value;
            alert(value)
        }
    }
    ReactDOM.render(<Demo />, document.getElementById("test"))
</script>

回调函数形式

<script type="text/babel">
    class Demo extends React.Component {
        render() {
            return (
                <div>
                    // 回调函数中的参数是代表节点本身,回调函数的意义是将该节点赋值给 示例 对象上
                    <input type="text" ref={c => this.input1 = c } placeholder="点击按钮提示数据" /> &nbsp;
                    <button onClick={this.showData}>点击提取左侧数据</button>&nbsp;
                    <input onBlur={this.showData2} ref={c => this.input2 = c} type="text" placeholder="失去焦点提示数据" />
                </div>
            )
        }
        showData = () => {
            // 拿到 dom 节点
            const input1 = this.input1;
            // 获取值
            const value = input1.value;
            alert(value)
        }
        showData2 = () => {
            // 拿到 dom 节点
            const input2 = this.input2;
            // 获取值
            const value = input2.value;
            alert(value)
        }
    }
    ReactDOM.render(<Demo />, document.getElementById("test"))
</script>

官方 API :createRef

<script type="text/babel">
    class Demo extends React.Component {
        /**
             * React.createRef 调用后可以返回一个容器,该容器可以存储被ref所标识的节点
             * 该容器是专人专用,一个容器只能存一个节点
             */
        myRef = React.createRef()
        myRef2 = React.createRef()
        render() {
            return (
                // ref={this.myRef} 将该节点存储到 myRef 容器中
                <div>
                    <input type="text" ref={this.myRef} placeholder="点击按钮提示数据" /> &nbsp;
                    <button onClick={this.showData}>点击提取左侧数据</button>&nbsp;
                    <input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据" />
                </div>
            )
        }
        showData = () => {
            // 拿到 dom 节点
            const input1 = this.myRef.current;
            // 获取值
            const value = input1.value;
            alert(value)
        }
        showData2 = () => {
            // 拿到 dom 节点
            const input2 = this.myRef2.current;
            // 获取值
            const value = input2.value;
            alert(value)
        }
    }
    ReactDOM.render(<Demo />, document.getElementById("test"))
</script>

总结

  • status 用来初始化值
  • props 用来传递参数(类式组件和函数式组件都可以使用)
  • ref 用来表示一个组件的标签,拿到对应的 dom 元素,相当于以前的 id

事件

当绑定事件的节点和要操作的节点是同一个节点的时候,事件可以用来解决 refs 过度使用的问题。。。

<script type="text/babel">
    class Demo extends React.Component {
        render() {
            return (
                <div>
                    <input onBlur={this.showData} type="text" placeholder="失去焦点提示数据" />
                </div>
            )
        }
        showData = (event) => {
            alert(event.target.value)
        }
    }
    ReactDOM.render(<Demo />, document.getElementById("test"))
</script>

收集表单数据

案例

需求: 定义一个包含表单的组件

输入用户名密码后, 点击登录提示输入信息

组件分类

  • 非受控组件 :表单中的输入类的组件,都是现用现取。
  • 受控组件 :输入数据时,将数据维护到状态中去,需要用的时候在从状态中取出来(双向绑定)。优点是省去了繁琐的 refs

非受控组件

<script type="text/babel">
    class Login extends React.Component {
        render() {
            return (
                <form 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>
            )
        }
        handleSubmit = (event) => {
            event.preventDefault() // 阻止表单提交,真实开发中可以在下面使用 ajax 发起请求
            const {username,password} = this
            alert(`用户名是 : ${username.value},密码是 : ${password.value}`)
        }
    }
    ReactDOM.render(<Login />, document.getElementById("test"))
</script>

受控组件

<script type="text/babel">
    class Login extends React.Component {
        // 初始化状态
        state = {
            username:'',
            password:''
        }
        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    用户名 : <input onChange={this.savaUsername} type="text" name="username" />
                    密码 : <input onChange={this.savePassword} type="password" name="password" />
                    <button>登陆</button>
                </form>
            )
        }
        savaUsername = (event) =>{
            this.setState({username:event.target.value})
        }
        savePassword = (event) =>{
            this.setState({password:event.target.value})
        }
        handleSubmit = (event) => {
            event.preventDefault() // 阻止表单提交,真实开发中可以在下面使用 ajax 发起请求
            const {username,password} = this.state
            alert(`用户名是 : ${username},密码是 : ${password}`)
        }
    }
    ReactDOM.render(<Login />, document.getElementById("test"))
</script>

高阶函数、函数柯里化

我们正常写方法的时候是 onChange={this.saveFormData},这样的话不写高阶函数,在组件加载的时候就会执行该方法

而使用了高阶函数之后就可以这样了onChange={this.saveFormData('username')}

高阶函数

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

  • 若A函数,接收的参数是一个函数。
  • 若A函数,调用的返回值是一个函数。

函数的柯里化

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

<script type="text/babel">
    class Login extends React.Component {
        // 初始化状态
        state = {
            username:'',
            password:''
        }
        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    用户名 : <input onChange={this.saveFormData('username')} type="text" name="username" />
                    密码 : <input onChange={this.saveFormData('password')} type="password" name="password" />
                    <button>登陆</button>
                </form>
            )
        }
        // 高阶函数、函数的柯里化
        saveFormData = (data) =>{
            return (event)=>{
                // 对象里面的变量 :[] 可以传入变量,如果不用 [] ,传入的是值
                this.setState({[data]:event.target.value})
            }
        }
        handleSubmit = (event) => {
            event.preventDefault() // 阻止表单提交,真实开发中可以在下面使用 ajax 发起请求
            const {username,password} = this.state
            alert(`用户名是 : ${username},密码是 : ${password}`)
        }
    }
    ReactDOM.render(<Login />, document.getElementById("test"))
</script>

不用柯里化

<script type="text/babel">
    class Login extends React.Component {
        // 初始化状态
        state = {
            username:'',
            password:''
        }
        render() {
            return (
                <form 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>
            )
        }
        saveFormData = (data,vevnt) =>{
            // 对象里面的变量 :[] 可以传入变量,如果不用 [] ,传入的是值
            this.setState({[data]:event.target.value})
        }
        handleSubmit = (event) => {
            event.preventDefault() // 阻止表单提交,真实开发中可以在下面使用 ajax 发起请求
            const {username,password} = this.state
            alert(`用户名是 : ${username},密码是 : ${password}`)
        }
    }
    ReactDOM.render(<Login />, document.getElementById("test"))
</script>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:43:36  更:2022-09-30 00:44:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 16:45:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码