Как сбросить счетчики в дочернем компоненте в React Native - PullRequest
0 голосов
/ 15 мая 2018

У меня есть компонент PlusMinus, цель которого - позволить пользователю увеличивать или уменьшать целое число.В моем родительском компоненте я перебираю несколько элементов в списке и предоставляю счетчик PlusMinus для каждого элемента.

Как я могу сбросить все счетчики из родительского компонента?Большинство ответов на подобные вопросы предполагают обработку состояния в родительском элементе, отключение дочернего состояния и передачу значений дочернему элементу с помощью реквизита.Тем не менее, когда я обновляю значения проп в родительском, потомок не обновляется.Какой-то компонент ответа WillReceiveProps.Однако эта функция устарела, и я все равно не смог заставить ее работать.

Вот мой компонент.Это работает, за исключением того, что я не могу сбросить счетчики.Как я могу предоставить кнопку в моем родителе, которая сбрасывает все дочерние счетчики?

import * as React from 'react'
import { Text, TouchableOpacity, View } from 'react-native'

import styles from './Styles'

type Props = { k: string, handler: Function, style: Object }
type State = { clicks: Object }

export default class PlusMinus extends React.Component<Props, State> {

  state = {
    clicks: {}
  }

  IncrementItem = (k: string) => {

    let clicks = this.state.clicks

    if ('undefined' == typeof this.state.clicks[k]) {
      clicks[k] = 1
    }
    else {
      clicks[k]++
    }

    // A handler passed from the parent that updates persistent values in the parent.
    this.props.handler(k, clicks[k])

    this.setState(
      { clicks: clicks }
    )
  }

  DecreaseItem = (k: string) => {

    let clicks = this.state.clicks

    if ('undefined' == typeof this.state.clicks[k]) {
      clicks[k] = 0
    }
    else if (this.state.clicks[k] > 0) {
      clicks[k]--
    }

    this.props.handler(k, clicks[k])

    this.setState(
      { clicks: clicks }
    )
  }

  Count = (k: string) => {
    let ct = 0

    if ('undefined' !== typeof this.state.clicks[k]) {
      ct = this.state.clicks[k]
      ct = ct++
    }
    return (
      <Text style={styles.counter} id={k}>{ ct }</Text>
    )
  }

  render() { 
    return (
      <View style={this.props.style}>
        <TouchableOpacity style={styles.plusminus} title='+' onPress={() => this.IncrementItem(this.props.k)}>
          <Text style={styles.pmtxt}>+</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.plusminus} title='-' onPress={() => this.DecreaseItem(this.props.k)}>
          <Text style={styles.pmtxt}>-</Text>
        </TouchableOpacity>

        <View style={[{ 
          paddingHorizontal: 10,
          marginLeft: 4,
          alignItems: 'center',
          justifyContent: 'center',
          backgroundColor: '#aaa',
          width: 40,
          borderRadius: 5
        }]}>{this.Count(this.props.k)}</View>
      </View>
    )
  }
}

Мой обработчик в родительском компоненте выглядит как ...

handler = async (key: string, value: Number) => {
    let object = {}
    let str = await Expo.SecureStore.getItemAsync('clicks')
    if (str) {
      object = JSON.parse(str)
    }
    object[key] = value
    str = JSON.stringify(object)
    Expo.SecureStore.setItemAsync('clicks', str)
  }

------ ОБНОВЛЕНИЕ: Вот рабочий пример.-------

import * as React from 'react'
import { Text, TouchableOpacity, View } from 'react-native'

import styles from './Styles'

type Props = { k: string, handler: Function, style: Object, clicks: Number }

export default class PlusMinus extends React.Component<Props> {

  IncrementItem = (k: string) => {
    let clicks = this.props.clicks
    this.props.handler(k, clicks, '++')
  }

  DecreaseItem = (k: string) => {
    let clicks = this.props.clicks
    this.props.handler(k, clicks, '--')
  }

  Count = (k: string) => {
    let ct = 0

    if ('undefined' !== typeof this.props.clicks) {
      ct = this.props.clicks
    }
    return (
      <Text style={styles.counter} id={k}>{ ct }</Text>
    )
  }

  render() { 
    return (
      <View style={this.props.style}>
        <TouchableOpacity style={styles.plusminus} title='+' onPress={() => this.IncrementItem(this.props.k)}>
          <Text style={styles.pmtxt}>+</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.plusminus} title='-' onPress={() => this.DecreaseItem(this.props.k)}>
          <Text style={styles.pmtxt}>-</Text>
        </TouchableOpacity>

        <View style={[{ 
          paddingHorizontal: 10,
          marginLeft: 4,
          alignItems: 'center',
          justifyContent: 'center',
          backgroundColor: '#aaa',
          width: 40,
          borderRadius: 5
        }]}>{this.Count(this.props.k)}</View>
      </View>
    )
  }
}

И рабочий обработчик для родительского компонента ...

 handler = async (key: string, value: Number, pm: string) => {

    let ct = 1
    let n = this.state.clicks[key]

    if ('++' == pm) {
      ct = n
      ct++
    }
    else {
      ct = 0
      if (n > 0) {
        ct = n
        ct--
      }
    }

    let clicks = this.state.clicks
    clicks[key] = ct

    this.setState({clicks: clicks})
  }

И JSX для дочернего компонента в рендере родительского компонента ...

<PlusMinus k={k} clicks={this.state.clicks[k]} style={{
                        flexWrap: 'wrap',
                        flexDirection: 'row',
                        marginBottom: 0,
                        marginRight: 12,
                        paddingBottom: 0,
                        paddingRight: 5,
                        paddingLeft: 5
                      }} handler={this.handler} />

1 Ответ

0 голосов
/ 15 мая 2018

Я считаю, что лучший подход - это именно то, что вы описали: ваш родительский компонент должен обрабатывать щелчки и передавать их как реквизиты дочернему компоненту, где число щелчков происходит из состояния, что-то вроде:

state = { clicks: [] }
...
<PlusMinus clicks={this.state.clicks[i]} />

Затем, когда вы хотите сбросить щелчки, вы просто запускаете цикл для this.state.clicks и устанавливаете все элементы в 0 (очевидно, вызывая setState с новым массивом).И, конечно, дочерний компонент может не иметь состояния, и функции увеличения / уменьшения должны перемещаться в родительский компонент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...