react-props扩展

本文探讨了如何在React中使用props.children模拟Vue插槽,包括具名插槽和匿名插槽,以及如何在类组件和函数组件中实现插槽。还介绍了prop-types的使用,用于类型限制和设置默认值以提高组件安全性。
摘要由CSDN通过智能技术生成

react - props用法扩展

props.children 模拟vue中的插槽

简单实用函数组件模拟插槽,和具名插槽

   const Child = ({children}) => {
        return(
            <div>
            {/* 具名插槽实现 , 对应元素的具体使用*/}
            <div> {children.find(itm => itm.props.name === 'header')}</ div>
            <h3>具名插槽</ h3>
            <div>{ children.find(itm => itm.props.name === 'footer')}</ div>
            
            <hr />
            {/* 直接将拿到的数据全部展示*/}
            <h3>简单插槽</ h3>
            <div>{children}</ div>
            </ div>
        )
   } 
   
    const Farther = () => {
        return (
            <div>
            <h3>父组件</ h3>
            
            {/*
                1, 子组件中的元素,可以通过props.children获取, 可以直接结构
                2, 如果只有一个元素,返回的是一个对象,如果有多个元素返回的就是一个对象数组
              */}
            <Child>
                <div name="header">我是头</ div>
                <div name="footer">我是尾</ div>
            </ Child>
            </ div>
        )
    }
`

### 模拟作用域插槽
>理解作用域插槽: 实现组件间数据传递和内容复用的技术 , 他允许父组件在子组件模版中自定义内容,同时还可以在访问到子组件时, 提供数据给父组件

```javascript
const AppChildren = ({ children }) => {
  const name = '迂幵'
  // 使用内置方法判断当前的children属性是对象还是数组,写法上都是以数组方式些
  const childs = React.Children.map(children, (child) => {
    // 在使用内置方法,克隆一个属于自己的组件
    return React.cloneElement(child, {
      onClick: () => {
        // 调用的是父组件中的子组件插槽传过来的点击事件 , 并将当前子组件中的数据,传入到父的子模版中
        child.props.onClick(name)
      }
    })
  })
  return (
    <div>
      <div>子组件</div>
      <hr />
      {childs}
    </div>
  );
}


const AppFarther = () => {
  const clickHandler = (name) => {
    console.log('2222' , name)
  }
  return (
    <div>
      <h3 >我是父组件</h3>

      <AppChildren>

        <div onClick={clickHandler}>点我,快点我</div>

      </AppChildren>
    </div>
  );
}

使用类组件模拟插槽

class AppChildrenCalss extends Component {
  render() {
    // 如果是写好了的子组件内容,可以直接调用即可
    const {children} = this.props
    // 是一个数组,每个jsx元素都是一个对象,定义在标签上的属性就是props值
    console.log(children)

    // 如果要拿到子组件内容后要修改显示内容或者样式之类的
    // 要修改的话一定要先克隆下来,不一定非用map , forEach也可以
    const Children = React.Children.map(this.props.children , child => {
      return React.cloneElement(child , {style : {color : 'red'}} , '这里修改显示内容')
    })
    return (
      <div>
        <h3>子组件</h3>
        <hr />
        {/* 修改的是克隆的,所以原本传过来的组件并不受影响,可以一块使用 */}
        {children}
        {Children}
        
        <hr />
        <hr />
        {/* 实现具名插槽 , 匿名插槽默认是有名字的: default */}
        {children.find(child => child.props.name === 'header')}
        {children.find(child => child.props.name === 'default' || !child.props.name)}
        {children.find(itm => itm.props.name === 'footer')}
      </div>
    );
  }
}


class AppChildrenCalss_F extends Component {
  render() {
    return (
      <div>
        <h3>父组件</h3>

        <AppChildrenCalss>
          <div>子组件的内容</div>
        </AppChildrenCalss>
      </div>
    );
  }
}

prop-types : 类型限制

react15.5之后,使用它时要重新安装 * npm i -S prop-types*
在自己封装公共组件的时候一定要用到,根据具体的业务需求封装的组件中值的类型也有一定限制
起作用: 来限制props类型,props本身可以是任意类型的数据,写法类似Ts,类组件函数组件都支持
资料查阅地址: react-propTypes

// 代码演示     函数组件

import React from 'react';
import types from 'prop-types'

const AppPropTypes = () => {
  return (
    <div>
      <h1>父组件</h1>
      <AppPropTypesChild
        countent='100'
        arr={[1, 'w3', 3, function a() { console.log('a') }(), 4]}
        obj={{ id: 1, name: '2', c: () => { console.log('func') } }}
        el={
          <div>
            <div>aaa</div>
            <div>bbb</div>
          </div>
        }
        sex = '2'
        text = 'aldsjfoajdojcoaidt'
      />

    </div>
  );
}

const AppPropTypesChild = (props) => {
  return (
    <div>
      {/* 如过展示的是数组中的函数的话,要么在存的时候字调用,要么在此处调用,不能直接展示函数体 */}
      {props.obj.a} --- {props.countent} --- {props.arr[3]}
    </div>
  );
}
// 限制子组件中接受到的值的类型,如果值得类型不符合限制类型,使用时可以正常使用,但控制台会有报错.这种写法,类组件,函数组件都可以用
AppPropTypesChild.propTypes = {
  // countent的值只能是一个数字类型
  // countent : types.number,
  // countent值必须要有并且是一个数字类型
  // countent : types.number.isRequired,
  // 设置为字符串类型
  // countent : types.string,
  // 字段类型可选,上中下摇摆
  countent: types.oneOfType([types.string, types.number, types.any]),
  // 字段类型为数组
  // arr : types.array,
  // 具体到数组中的每个元素的类型  所有的元素类型都一样的情况
  // arr : types.arrayOf(types.number),
  // 数组中的元素的值类型不同
  arr: types.arrayOf(types.oneOfType([types.string, types.number, types.bool, types.func])),
  // 对象类型,这样写的范围太广了
  obj : types.object,
  // 限制对象中属性的类型,具体对应每一个,没对应到的会报错
  obj: types.shape({
    id : types.number,
    name : types.string,
    c : types.func
  }),
  // 元素类型
  el: types.node,
  // 枚举类型, 赋值正能在规定的范围内 '1' 或者 '2'
  sex : types.oneOf(['1','2']),
  // 自定义验证
  text : (props , propName , componentName) => {
    if(props[propName].includes('t')){
      return new Error('有敏感词t出现')
    }
  }

}

export default AppPropTypes;

在类组件中还可以换一种写法,写前先来明确一点: class.shuxing 此属性是一个静态属性 ===> Child.propTypes={} 就可以理解为在类中定义一个静态属性
在导入types时,可以直接将进行结构,不过这样挺麻烦的,还是别结构了

import {string , number , array , onOF ,...} from 'prop-typs'
class Child extends Component{
    static propTypes = {
        countent : string,
        .....
    }
}

props的默认值设置

组件中提过,在子组件中可以对父组件传过来的props进行结构,并赋予初始值,但是这有缺陷
结构式需要开发者调用组件时,一定要定义默认值,如果不设置,可能造成组件异常,不安全

// 具体定义默认值的写法,函数/类组件通用的,很简单
Child.defaultProps = {
    count : 100,
    .... 
}
  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
react-native-redux-router是一个用于在React Native应用中管理路由和状态的库。它结合了React Native、Redux和React Navigation,提供了一种方便的方式来处理应用程序的导航和状态管理。 下面是一个简单的示例,演示了如何在React Native应用中使用react-native-redux-router: 1. 首先,安装所需的依赖项。在终端中运行以下命令: ```shell npm install react-native react-redux redux react-navigation react-native-router-flux --save ``` 2. 创建一个Redux store,并将其与React Native应用程序的根组件连接起来。在App.js文件中,添加以下代码: ```javascript import React from 'react'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import rootReducer from './reducers'; import AppNavigator from './navigation/AppNavigator'; const store = createStore(rootReducer); export default function App() { return ( <Provider store={store}> <AppNavigator /> </Provider> ); } ``` 3. 创建一个导航器组件,并定义应用程序的导航结构。在navigation/AppNavigator.js文件中,添加以下代码: ```javascript import { createAppContainer } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { Actions } from 'react-native-router-flux'; import HomeScreen from '../screens/HomeScreen'; import DetailsScreen from '../screens/DetailsScreen'; const MainNavigator = createStackNavigator({ Home: { screen: HomeScreen }, Details: { screen: DetailsScreen }, }); const AppNavigator = createAppContainer(MainNavigator); const mapStateToProps = state => ({ // 将Redux状态映射到导航器组件的props中 }); const mapDispatchToProps = dispatch => bindActionCreators(Actions, dispatch); export default connect(mapStateToProps, mapDispatchToProps)(AppNavigator); ``` 4. 创建屏幕组件,并在其中使用导航和Redux状态。在screens/HomeScreen.js文件中,添加以下代码: ```javascript import React from 'react'; import { View, Text, Button } from 'react-native'; import { Actions } from 'react-native-router-flux'; const HomeScreen = () => { return ( <View> <Text>Welcome to the Home Screen!</Text> <Button title="Go to Details" onPress={() => Actions.details()} /> </View> ); } export default HomeScreen; ``` 5. 创建其他屏幕组件,并在其中使用导航和Redux状态。在screens/DetailsScreen.js文件中,添加以下代码: ```javascript import React from 'react'; import { View, Text, Button } from 'react-native'; import { Actions } from 'react-native-router-flux'; const DetailsScreen = () => { return ( <View> <Text>Welcome to the Details Screen!</Text> <Button title="Go back" onPress={() => Actions.pop()} /> </View> ); } export default DetailsScreen; ``` 这是一个简单的示例,演示了如何在React Native应用中使用react-native-redux-router来管理路由和状态。你可以根据自己的需求进行扩展和定制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值