Heim >Web-Frontend >js-Tutorial >So kapseln Sie eine mehrstufige React Native-Verknüpfung (Code-Implementierung)

So kapseln Sie eine mehrstufige React Native-Verknüpfung (Code-Implementierung)

不言
不言Original
2018-09-19 16:55:261943Durchsuche

Der Inhalt dieses Artikels befasst sich mit der Kapselung einer mehrstufigen React-Native-Verknüpfung (Code-Implementierung). Ich hoffe, dass er für Sie hilfreich ist.

Hintergrund

Es muss kürzlich ein Projekt geben, das eine sekundäre Verknüpfungsfunktion erfordert!
Ursprünglich wollte ich es komplett verpacken und auf Github stellen, um Sterne zu verdienen, aber ich habe festgestellt, dass es bereits relativ ausgereifte auf dem Markt gibt. Warum habe ich nicht vor der Entwicklung danach gesucht (das Projekt war in Eile). ) Jetzt, wo es verpackt ist, reden wir über den Prozess

Die Aufgabe beginnt

Bevor ein Bauteil verpackt wird, Sie müssen zunächst ungefähr wissen, wie die Komponente aussieht. Verstehen Sie den Umriss

So kapseln Sie eine mehrstufige React Native-Verknüpfung (Code-Implementierung) 2. Überlegen Sie sich die Struktur

Vor dem Verpacken , denken Sie darüber nach

1 Welche Funktionen muss diese Komponente erfüllen?

Nachdem Sie die erste Ebene geändert haben, ändert sich die zweite Ebene entsprechend. Wenn Sie die zweite Ebene ändern, ändert sich auch die dritte Ebene usw. Sie können die Elemente angeben, die ausgewählt werden müssen. und Sie können den Wert jeder Ebene dynamisch ändern

2. Was sind die offengelegten APIs?

// 已封装的组件(Pickers.js)
import React, { Component } from 'react'
import Pickers from './Pickers'

class Screen extends Component {
  constructor (props) {
    super(props)
    this.state = {
      defaultIndexs: [1, 0], // 指定选择每一级的第几项,可以不填不传,默认为0(第一项)
      visible: true,  // 
      options: [ // 选项数据,label为显示的名称,children为下一级,按需加载直接改变options的值就行了
        {
          label: 'A',
          children: [
            {
              label: 'J'
            },
            {
              label: 'K'
            }
          ]
        },
        {
          label: 'B',
          children: [
            {
              label: 'X'
            },
            {
              label: 'Y'
            }
          ]
        }
      ]
    }
  }
  onChange(arr) { // 选中项改变时触发, arr为当前每一级选中项索引,如选中B和Y,此时的arr就等于[1,1]
    console.log(arr)
  }
  onOk(arr) { // 最终确认时触发,arr同上
    console.log(arr)
  }
  render() {
    return (
      <view>
        <pickers>
        </pickers>
      </view>
    )
  }
}
In der frühen Phase wird die API häufig während des Kapselungsprozesses hinzugefügt und geändert und kann flexibel an die tatsächliche Situation angepasst werden

3 Wie um es für Benutzer komfortabler zu machen?

Unter Verwendung derzeit gängiger Datenstrukturen und -stile (Sie können von anderen Komponenten lernen) ist die Definition des Schnittstellennamens auf einen Blick klar

4 zu weiteren Szenarien?

Kapselt nur Funktionen, nicht geschäftlich

3. Beginnen Sie mit dem Schreiben von Code

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
  StyleSheet,
  View,
  Text,
  TouchableOpacity,
} from 'react-native'

class Pickers extends Component {
  static propTypes = {
    options: PropTypes.array,
    defaultIndexs: PropTypes.array,
    onClose: PropTypes.func,
    onChange: PropTypes.func,
    onOk: PropTypes.func,
  }

  constructor (props) {
    super(props)
    this.state = {
      options: props.options, // 选项数据
      indexs: props.defaultIndexs || [] // 当前选择的是每一级的每一项,如[1, 0],第一级的第2项,第二级的第一项
    }
    this.close = this.close.bind(this) // 指定this
    this.ok = this.ok.bind(this) // 指定this
  }
  close () { // 取消按钮事件
    this.props.onClose && this.props.onClose()
  }

  ok () { // 确认按钮事件
    this.props.onOk && this.props.onOk(this.state.indexs)
  }
  onChange () { // 选项变化的回调函数

  }
  renderItems () { // 拼装选择项组

  }

  render() {
    return (
      <view>
        <touchableopacity>
          <touchableopacity>
            <view>
              {this.renderItems()}
            </view>
            <view>
              <touchableopacity>
                <text>取消</text>
              </touchableopacity>
              <touchableopacity>
                <text>确认</text>
              </touchableopacity>
            </view>
          </touchableopacity>
        </touchableopacity>
      </view>
    )
  }
}

Die Zusammenstellung von Auswahlelementgruppen ist die Kernfunktion und eine separate Funktion (renderItems ) wird vorgeschlagen, praktisch für die Verwaltung und spätere Wartung

 renderItems () { // 拼装选择项组
    const items = []
    const { options = [], indexs = [] } = this.state
    const re = (arr, index) => { // index为第几级
      if (arr && arr.length > 0) {
        const childIndex = indexs[index] || 0 // 当前级指定选中第几项,默认为第一项
        items.push({
          defaultIndex: childIndex,
          values: arr //当前级的选项列表
        })
        if (arr[childIndex] && arr[childIndex].children) {
          const nextIndex = index + 1
          re(arr[childIndex].children, nextIndex)
        }
      }
    }
    re(options, 0) // re为一个递归函数
    return items.map((obj, index) => {
      return ( // PickerItem为单个选择项,list为选项列表,defaultIndex为指定选择第几项,onChange选中选项改变时回调函数,itemIndex选中的第几项,index为第几级,如(2, 1)为选中第二级的第三项
        <pickeritem> { this.onChange(itemIndex, index)}}
          />
      )
    })
  }</pickeritem>

PickerItem ist eine einzelne Auswahlkomponente. Der integrierte Picker in React Native hat unterschiedliche Stile auf Android und IOS Verwenden Sie PickerItem. Um es im Inneren zu ändern, müssen Sie nur dieselbe Schnittstelle bereitstellen, was bedeutet, dass PickerItem unabhängig und einfach zu warten ist.

// 单个选项
class PickerItem extends Component {
  static propTypes = {
    list: PropTypes.array,
    onChange: PropTypes.func,
    defaultIndex: PropTypes.number,
  }

  static getDerivedStateFromProps(nextProps, prevState) { // list选项列表和defaultIndex变化之后重新渲染
    if (nextProps.list !== prevState.list ||
        nextProps.defaultIndex !== prevState.defaultIndex) {
      return {
        list: nextProps.list,
        index: nextProps.defaultIndex
      }
    }
    return null
  }

  constructor (props) {
    super(props)
    this.state = {
      list: props.list,
      index: props.defaultIndex
    }
    this.onValueChange = this.onValueChange.bind(this)
  }

  onValueChange (itemValue, itemIndex) {
    this.setState( // setState不是立即渲染
      {
        index: itemIndex
      },
      () => {
        this.props.onChange && this.props.onChange(itemIndex)
      })

  }

  render() {
    // Picker的接口直接看react native的文档https://reactnative.cn/docs/picker/
    const { list = [], index = 0 } = this.state
    const value = list[index]
    const Items = list.map((obj, index) => {
      return <picker.item></picker.item>
    })
    return (
      <picker>
        {Items}
      </picker>
    )
  }
}

Die Rückruffunktion onChange von PickerItem in renderItems()

 onChange (itemIndex, currentIndex) { // itemIndex选中的是第几项,currentIndex第几级发生了变化
    const indexArr = []
    const { options = [], indexs = [] } = this.state
    const re = (arr, index) => { // index为第几层,循环每一级
      if (arr && arr.length > 0) {
        let childIndex
        if (index  {
        this.props.onChange && this.props.onChange(indexArr)
      }
    )
  }

Zusammenfassung

Es gibt viele ausgereifte Mehrebenenverknüpfungen auf dem Markt. Wenn die funktionalen Anforderungen relativ hoch sind, empfiehlt es sich, ausgereifte Komponenten zu verwenden. Dadurch ist der Entwicklungsaufwand gering und die Dokumentation ist vollständig , und es ist für andere Leute im Team einfach, die Leitung zu übernehmen. Wenn Sie nur sehr einfache Funktionen verwenden, empfiehlt es sich, es selbst zu entwickeln. Es ist nicht erforderlich, auf ein großes Paket zu verweisen. Sie können es nur selbst entwickeln. Unabhängig von der oben genannten Situation ist es gut, das Funktionsprinzip im Inneren zu verstehen

Die Hauptanweisungen befinden sich im Code. Sie können den vollständigen Code auch direkt kopieren, um zu sehen, ob nicht viel Inhalt vorhanden ist Sie müssen den entsprechenden Wert direkt über abrufen. Überprüfen Sie einfach den entsprechenden Wert des erhaltenen Index

Vollständiger Code

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
  StyleSheet,
  View,
  Text,
  Picker,
  TouchableOpacity,
} from 'react-native'

// 单个选项
class PickerItem extends Component {
  static propTypes = {
    list: PropTypes.array,
    onChange: PropTypes.func,
    defaultIndex: PropTypes.number,
  }

  static getDerivedStateFromProps(nextProps, prevState) { // list选项列表和defaultIndex变化之后重新渲染
    if (nextProps.list !== prevState.list ||
        nextProps.defaultIndex !== prevState.defaultIndex) {
      return {
        list: nextProps.list,
        index: nextProps.defaultIndex
      }
    }
    return null
  }

  constructor (props) {
    super(props)
    this.state = {
      list: props.list,
      index: props.defaultIndex
    }
    this.onValueChange = this.onValueChange.bind(this)
  }

  onValueChange (itemValue, itemIndex) {
    this.setState( // setState不是立即渲染
      {
        index: itemIndex
      },
      () => {
        this.props.onChange && this.props.onChange(itemIndex)
      })

  }

  render() {
    // Picker的接口直接看react native的文档https://reactnative.cn/docs/picker/
    const { list = [], index = 0 } = this.state
    const value = list[index]
    const Items = list.map((obj, index) => {
      return <picker.item></picker.item>
    })
    return (
      <picker>
        {Items}
      </picker>
    )
  }
}

// Modal 安卓上无法返回
class Pickers extends Component {
  static propTypes = {
    options: PropTypes.array,
    defaultIndexs: PropTypes.array,
    onClose: PropTypes.func,
    onChange: PropTypes.func,
    onOk: PropTypes.func,
  }
  static getDerivedStateFromProps(nextProps, prevState) { // options数据选项或指定项变化时重新渲染
    if (nextProps.options !== prevState.options ||
        nextProps.defaultIndexs !== prevState.defaultIndexs) {
      return {
        options: nextProps.options,
        indexs: nextProps.defaultIndexs
      }
    }
    return null
  }
  constructor (props) {
    super(props)
    this.state = {
      options: props.options, // 选项数据
      indexs: props.defaultIndexs || [] // 当前选择的是每一级的每一项,如[1, 0],第一级的第2项,第二级的第一项
    }
    this.close = this.close.bind(this) // 指定this
    this.ok = this.ok.bind(this) // 指定this
  }
  close () { // 取消按钮事件
    this.props.onClose && this.props.onClose()
  }

  ok () { // 确认按钮事件
    this.props.onOk && this.props.onOk(this.state.indexs)
  }
  onChange (itemIndex, currentIndex) { // itemIndex选中的是第几项,currentIndex第几级发生了变化
    const indexArr = []
    const { options = [], indexs = [] } = this.state
    const re = (arr, index) => { // index为第几层,循环每一级
      if (arr && arr.length > 0) {
        let childIndex
        if (index  {
        this.props.onChange && this.props.onChange(indexArr)
      }
    )
  }
  renderItems () { // 拼装选择项组
    const items = []
    const { options = [], indexs = [] } = this.state
    const re = (arr, index) => { // index为第几级
      if (arr && arr.length > 0) {
        const childIndex = indexs[index] || 0 // 当前级指定选中第几项,默认为第一项
        items.push({
          defaultIndex: childIndex,
          values: arr //当前级的选项列表
        })
        if (arr[childIndex] && arr[childIndex].children) {
          const nextIndex = index + 1
          re(arr[childIndex].children, nextIndex)
        }
      }
    }
    re(options, 0) // re为一个递归函数
    return items.map((obj, index) => {
      return ( // PickerItem为单个选择项,list为选项列表,defaultIndex为指定选择第几项,onChange选中选项改变时回调函数
         { this.onChange(itemIndex, index)}}
          />
      )
    })
  }

  render() {
    return (
      
        
          
            
              {this.renderItems()}
            
            
              
                取消
              
              
                确认
              
            
          
        
      
    )
  }
}

const styles = StyleSheet.create({
  box: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    zIndex: 9999,
  },
  bg: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.4)',
    justifyContent: 'center',
    alignItems: 'center'
  },
  dialogBox: {
    width: 260,
    flexDirection: "column",
    backgroundColor: '#fff',
  },
  pickerBox: {
    flexDirection: "row",
  },
  btnBox: {
    flexDirection: "row",
    height: 45,
  },
  cancelBtn: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    borderColor: '#4A90E2',
    borderWidth: 1,
  },
  cancelBtnText: {
    fontSize: 15,
    color: '#4A90E2'
  },
  okBtn: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#4A90E2',
  },
  okBtnText: {
    fontSize: 15,
    color: '#fff'
  },
})

export default Pickers

Das obige ist der detaillierte Inhalt vonSo kapseln Sie eine mehrstufige React Native-Verknüpfung (Code-Implementierung). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn