zoukankan      html  css  js  c++  java
  • React Props、列表渲染、条件渲染

    目录:

    1. Props 概念

    2. 不同类组件 Props 传递

    3. 列表渲染

    4. 条件渲染

    一、Props 概念

    什么是 props

      当 React 元素作为自定义组件,将 JSX 所接受的属性转换为单个对象传递给组件,这个对象被称为“props”。

      更简单的理解是,props 是父组件传递给子组件的一个参数对象。

      从字面意思上来看,props 是 properties 的缩写,就是属性的意思。

    props 有哪些规则跟属性

      props 是组件的固有属性,它是通过 JSX 标签传递给子组件的。

      不可在组件内部对 props 进行修改。

      如果需要更新 props,需要通过父组件重新传入新的 props ,更新子组件。从这个意义上来讲,React 是单向数据流,props 就是从父组件传向子组件的数据。

    二、不同类组件 Props 传递

    类组件对 props 的传递

    下面举例,实现将父组件中定义的商品信息传递给子组件并进行渲染。listItem.jsx 是 App.js 的子组件。

    index.html:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
        <title>React App</title>
      </head>
      <body>
        <div id="root"></div>
      </body>
    </html>
    index.html

    index.js(React入口文件):

    导入 App.js,在页面上渲染 App 组件。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import 'bootstrap/dist/css/bootstrap.css';
    
    ReactDOM.render( <App />, document.getElementById('root'));
    index.js

    App.js:

    注册引用子组件 listItem.jsx。创建一个 listData 数组,将 props 命名为 data,通过 data 将定义好的数据传递给子组件,这里传递了 listData[0] 跟 listDate[1]。

    import React from 'react';
    import ListItem from './components/listItem'
    
    const listDate = [
        {
            id: 1,
            name: '红苹果',
        },
        {
            id: 2,
            name: '青苹果',
        },
    
    ]
    
    function App() {
        return(
            <div className="container">
                <ListItem data={ listDate[0] } />
                <ListItem data={ listDate[1] } />
            </div>
        )
    }
    
    export default App;
    App.js

    listItem.jsx:

    创建一个 constructor 方法,将 props 作为参数传入,调用 super 方法,因为 JS 强制规定子类的构造函数必须先调用一次 super 函数。然后将 props 的数据加载到元素上。

    import React, { Component } from 'react';
    
    class ListItem extends Component {
        constructor( props ){
            super(props)
        }
        render() { 
            return ( 
                <div className="row">
                    <div className="col-2">{this.props.data.id}</div>
                    <div className="col-2">{this.props.data.name}</div>
                </div>
            );
        }
    }
    
    export default ListItem;
    listItem.jsx

    页面表现:

     函数组件对 props 的传递

    下面举例,实现跟上面例子相同的效果。

    index.js (React入口文件):

    导入 App.js,在页面上渲染 App 组件。

    index.js

    App.js :

    注册引用子组件 listItemFunc.jsx

    import React from 'react';
    import ListItem from './components/listItemFunc'
    
    const listDate = [
        {
            id: 1,
            name: '红苹果',
        },
        {
            id: 2,
            name: '青苹果',
        },
    
    ]
    
    function App() {
        return(
            <div className="container">
                <ListItem data={ listDate[0] } />
                <ListItem data={ listDate[1] } />
            </div>
        )
    }
    
    export default App;
    App.js

    listItemFunc.jsx:

    import React from 'react';
    
    const ListItem = (props) => {
        return ( 
            <div className="row">
                <div className="col-2">{props.data.id}</div>
                <div className="col-2">{props.data.name}</div>
            </div>
        );
    }
     
    export default ListItem;
    listItemFunc.jsx

    需要在函数组件引入 React,因为不管是函数组件还是类组件都会通过 Babel 来转换为浏览器执行的代码。

    如果有下载 Simple React Snippets 插件,可以使用 sfc 缩写快速创建函数组件。

    定义一个 ListItem 函数,props 作为参数传入。

    函数组件没有 this 关键字,也就是说,需要将 this.props 替换为 props。

    函数组件与类组件的其中一个区别是,函数组件的 props 是直接通过函数参数的形式传递的。

    页面表现:

    函数组件要素

    ● 函数组件也叫无状态组件

    ● 组件内部没有 this (组件实例)

    ● 没有生命周期

    (有 React Hook 在函数组件中也可以使用状态以及生命周期)

    函数组件的优点:比较轻量。如果组件没有涉及状态,只是用于渲染数据的话,那么可以使用函数组件,这样可以拥有更好的性能,它就是一个纯函数,当有相同的输入时就会有相同的输出,没有任何副作用。

    三、列表渲染

    React 的 JSX 不是模板引擎,所以,需要通过 JS 的表达式形式来达到相应的需求。React 使用 map 方法实现列表渲染。

     例子

    index.js(React入口文件):

    导入 App.js,在页面上渲染 App 组件。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import 'bootstrap/dist/css/bootstrap.css';
    
    ReactDOM.render( <App />, document.getElementById('root'));
    index.js

    App.js:

    注册引用子组件 listItem.jsx。创建一个 listData 数组。

    使用 map 方法进行列表渲染,在 listData 数组上使用 map 方法,参数里的函数会作用于数组中的每一个元素,函数的参数 item 是指遍历到的当前元素,函数返回子组件<ListItem>,将 item 作为 props 赋给每一个子元素。

    每一个列表都需要有一个 key 属性值,因为 React 必须知道每个元素的独立标识,key 帮助识别哪些元素改变了(比如说被添加/删除了),React 需要快速地知道虚拟 DOM 哪里发生了变化而快速地找到真实 DOM。因此,在做列表渲染的时候,特别是数据量相当庞大的时候,应当给数组中的每一个元素赋予一个确定的标识。下面例子中将商品的 id 赋予给 key。属性 key 不会渲染在 DOM 上,key 只是给 React 内部做一个标识的认定。数组元素的 key 在其兄弟节点之间要是独一无二的。

    import React from 'react';
    import ListItem from './components/listItem'
    
    const listData = [
        {
            id: 1,
            name: '红苹果',
        },
        {
            id: 2,
            name: '青苹果',
        },
    
    ]
    
    function App() {
        return(
            <div className="container">
                {listData.map( item => {
                    return <ListItem key={item.id} data={ item }/>
                })}
            </div>
        )
    }
    
    export default App;
    App.js

    listItem.jsx:

    传入 props,引用 props

    import React, { Component } from 'react';
    
    class ListItem extends Component {
        constructor( props ){
            super(props);
            this.state = {};//不加这条语句会报错//暂时不懂为什么    
        }
        render() { 
            return ( 
                <div className="row">
                    <div className="col-2">{this.props.data.id}</div>
                    <div className="col-2">{this.props.data.name}</div>
                </div>
            );
        }
    }
    
    export default ListItem;
    listItem.jsx

    四、条件渲染

       React 的 JSX 不是模板引擎,所以,需要通过 JS 的表达式形式来达到相应的需求。条件渲染的方法比列表渲染的方法多,下面介绍 3 中常用的方法。

    1. 使用三目运算符( boolean ? case1 : case2 )

    2. 使用函数做条件判断

    3. 使用与运算符 && 判断

    使用三目运算符( boolean ? case1 : case2 )

      例 子  

    实现用三目运算符判断样式。在 index.css 里定义样式 themed-grid-col 跟 themed-grid-col-s ,在 listItem.jsx 中使用三目运算符进行判断,如果 count 为 0 则用样式 themed-grid-col-s,否则用样式 themed-grid-col。

    index.js(React入口文件):

    导入 App.js,在页面上渲染 App 组件。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css'
    import App from './App';
    import 'bootstrap/dist/css/bootstrap.css';
    
    ReactDOM.render( <App />, document.getElementById('root'));
    index.js

    App.js:

    注册引用子组件 listItem.jsx。

    import React from 'react';
    import ListItem from './components/listItem'
    
    const listData = [
        {
            id: 1,
            name: '红苹果',
        },
        {
            id: 2,
            name: '青苹果',
        },
    
    ]
    
    function App() {
        return(
            <div className="container">
                {listData.map( item => {
                    return <ListItem key={item.id} data={ item }/>
                })}
            </div>
        )
    }
    
    export default App;
    App.js

    index.css:

    存放样式,在 listItem.jsx 中会用到样式 themed-grid-col 跟 themed-grid-col-s。

    body {
      margin: 0;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
        'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
        sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    code {
      font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
        monospace;
    }
    
    .themed-grid-col {
      padding-top: 15px;
      padding-bottom: 15px;
      background-color: rgba(255, 255, 255);
      border: 1px solid rgba(86, 61, 124, 0.2);
    }
    
    .themed-grid-col-s {
      padding-top: 15px;
      padding-bottom: 15px;
      background-color: rgba(86, 61, 124, 0.2);
      border: 1px solid rgba(86, 61, 124, 0.2);
    }
    index.css

    listItem.jsx:

    import React, { Component } from 'react';
    
    let count = 0;
    
    class ListItem extends Component {
        constructor( props ){
            super(props);
            this.state = {};//不加这条语句会报错//暂时不懂为什么    
        }
        render() { 
            return ( 
                <div className="row mb-3">
                    <div className="col-2 themed-grid-col">{this.props.data.id}</div>
                    <div className="col-6 themed-grid-col">
                        <span>
                            {this.props.data.name}
                        </span>
                    </div>
                    <div className={"col-2 themed-grid-col" + (count ? '' : '-s')}>
                        {count}
                    </div>
                </div>
            );
        }
    }
    
    export default ListItem;
    listItem.jsx

    (  第 19 行可以用 es6 语法写,可以改成  )

    页面表现:

    因为 count 是 0 , 所以样式是 themed-grid-col-s (背景颜色为灰色)。

    使用函数做条件判断

     例 子 

    在前面例子的基础上,在 App.js 中使用函数 renderList 做一个条件判断。如果 listData 为空数组,则返回提示”购物车是空的“,如果不为空,则正常返回 React 元素。在 render 表达式里直接调用 this.renderList()  。

    import React, { Component } from 'react';
    import ListItem from './components/listItem'
    
    const listData = [
        {
            id: 1,
            name: '红苹果',
        },
        {
            id: 2,
            name: '青苹果',
        },
    ]
    
    class App extends Component {
        renderList(){
            if(listData.length === 0){
                return <div className="text-center">购物车是空的</div>
            }
            return listData.map( item => {
                return <ListItem key={item.id} data={ item }/>
            })
        }
        render() { 
            return(
                <div className="container">
                    { this.renderList() }
                </div>
            )
        }
    }
     
    export default App;
    App.js

    页面表现:

    listData 为空数组时:

    listData 不为空数组时:

    使用与运算符 && 判断

     例 子 

    在上面使用函数做条件判断的例子的基础上,修改 App.js。

    与运算符 && 最基本的使用方法是:当 && 前后的表达式都是 true,就会返回 true,否则返回 false。在这个例子中使用 && 判断的原理是:&& 的前面如果是 false,会直接返回 false/空字符串/零/null/undefined。如果 && 前面是 true,那么会返回 && 后面的表达式。在本例中,当 && 前面的“ listData.length === 0 ”为 true,会返回 && 后面的React元素 “ <div className="text-center"> 购物车是空的</div>”。

    本例中使用 && 判断的语句是:

    { listData.length === 0 && <div className="text-center">购物车是空的</div> }
    import React, { Component } from 'react';
    import ListItem from './components/listItem'
    
    const listData = [
        {
            id: 1,
            name: '红苹果',
        },
        {
            id: 2,
            name: '青苹果',
        },
    ]
    
    class App extends Component {
        renderList(){
            return listData.map( item => {
                return <ListItem key={item.id} data={ item }/>
            })
        }
        render() { 
            return(
                <div className="container">
                    { listData.length === 0 && <div className="text-center">购物车是空的</div> }
                    { this.renderList() }
                </div>
            )
        }
    }
     
    export default App;
    App.js

    页面表现:

    listData 为空时:

    listData 不为空时:

  • 相关阅读:
    vim python extension
    aws msk
    Install python3
    sns
    inventory
    批量添加监听端口
    template screen
    DNS name
    add jar and proxy repo
    模型诊断论文心得
  • 原文地址:https://www.cnblogs.com/xiaoxuStudy/p/13294941.html
Copyright © 2011-2022 走看看