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 不为空时:

原文地址:https://www.cnblogs.com/xiaoxuStudy/p/13294941.html