React-Native: нажатие на кнопку дважды только обновляет this.setState - PullRequest
0 голосов
/ 23 сентября 2019

Приложение простое. Конвертация газа. Что я пытаюсь сделать, это умножить Inputed Amount на 2, как если бы это была формула.Итак, у меня есть index.js, который является Parent, и Calculate.component.js, который делает все вычисления.Что я хочу, так это то, что index.js передаст inputed value в component, выполнит вычисления и снова передаст его index.js, чтобы отобразить вычисленную сумму.

Index.js

import React, { Component } from 'react';
import { Text } from 'react-native';
import styled from 'styled-components';
import PickerComponent from './Picker.Component';
import CalculateAVGAS from './Calculate.component';

export default class PickerAVGAS extends Component {
  static navigationOptions = ({ navigation }) => ({
    title: navigation.getParam('headerTitle'),
    headerStyle: {
      borderBottomColor: 'white',
    },
  });

  state = {
    gasTypeFrom: 'Gas Type',
    gasTypeTo: 'Gas Type',
    input_amount: '',
    pickerFrom: false,
    pickerTo: false,
    isResult: false,
    result: '',
  };

  inputAmount = amount => {
    this.setState({ input_amount: amount });
    console.log(amount);
  };

  onResult = value => {
    this.setState({
      result: value,
    });
    console.log('callback ', value);
  };

  render() {
    return (
      <Container>
        <Input
          placeholder="Amount"
          multiline
          keyboardType="numeric"
          onChangeText={amount => this.inputAmount(amount)}
        />
        <ResultContainer>
          <ResultText>{this.state.result}</ResultText>
        </ResultContainer>
        <CalculateContainer>
          <CalculateAVGAS
            title="Convert"
            amount={this.state.input_amount}
            total="total"
            titleFrom={this.state.gasTypeFrom}
            titleTo={this.state.gasTypeTo}
            // isResult={this.toggleResult}
            result={value => this.onResult(value)}
          />
        </CalculateContainer>
      </Container>
    );
  }
}

Рассчитать AVGAS / компонент

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

export default class CalculateAVGAS extends Component {
  static propTypes = {
    amount: PropTypes.string.isRequired,
    titleFrom: PropTypes.string.isRequired,
    titleTo: PropTypes.string.isRequired,
    title: PropTypes.string.isRequired,
  };

  state = {
    totalVisible: true,
    result: '',
  };

  onPressConversion = () => {
    const formula = this.props.amount * 2;
    const i = this.props.result(this.state.result);
    this.setState({ result: formula });
    // console.log(this.state.result);
    console.log('func()');
  }

  render() {
    return (
      <ButtonContainer onPress={() => this.onPressConversion()}>
        <ButtonText>{this.props.title}</ButtonText>
      </ButtonContainer>
    );
  }
}

После этого setStateобновляется только при двойном нажатии Convert button

1 Ответ

0 голосов
/ 23 сентября 2019

Ваша проблема здесь в том, что вы хотите отобразить информацию в родительском компоненте, но вы сохраняете эту информацию в состоянии дочернего компонента.Просто передайте сумму и результат дочернему компоненту без сохранения состояния (CalculateAVGAS).

Обычно лучше всего сохранять дочерние компоненты "тупыми" (то есть презентационными) и просто передавать информацию, необходимую для отображения, а также любуюфункции, которые должны быть выполнены, как реквизит.

import React, {Component} from 'react';
import styled from 'styled-components';

export default class CalculateAVGAS extends Component {
  onPressConversion = () => {
    this.props.result(this.props.amount * 2);
  };

  render() {
    return (
      <ButtonContainer onPress={() => this.onPressConversion()}>
        <ButtonText>{this.props.title}</ButtonText>
      </ButtonContainer>
    );
  }
}

const ButtonContainer = styled.TouchableOpacity``;

const ButtonText = styled.Text``;

Родительский компонент выглядит так:

import React, {Component} from 'react';
import {Text} from 'react-native';
import styled from 'styled-components';
import CalculateAVGAS from './Stack';

export default class PickerAVGAS extends Component {
  static navigationOptions = ({navigation}) => ({
    title: navigation.getParam('headerTitle'),
    headerStyle: {
      borderBottomColor: 'white',
    },
  });

  state = {
    gasTypeFrom: 'Gas Type',
    gasTypeTo: 'Gas Type',
    input_amount: null,
    pickerFrom: false,
    pickerTo: false,
    isResult: false,
    result: null,
  };

  inputAmount = amount => {
    this.setState({input_amount: amount});
  };

  onResult = value => {
    this.setState({
      result: value,
    });
  };

  render() {
    return (
      <Container>
        <Input
          placeholder="Amount"
          multiline
          keyboardType="numeric"
          onChangeText={amount => this.inputAmount(amount)}
        />
        <ResultContainer>
          <ResultText>{this.state.result}</ResultText>
        </ResultContainer>
        <CalculateContainer>
          <CalculateAVGAS
            title="Convert"
            amount={this.state.input_amount}
            total="total"
            titleFrom={this.state.gasTypeFrom}
            titleTo={this.state.gasTypeTo}
            result={value => this.onResult(value)}
          />
        </CalculateContainer>
      </Container>
    );
  }
}

const Container = styled.View``;

const ResultContainer = styled.View``;

const ResultText = styled.Text``;

const CalculateContainer = styled.View``;

const Input = styled.TextInput``;
...