首页 > 解决方案 > 创建自动禁用并在完成工作后自动重新启用的按钮

问题描述

我的 javascript/react 技能不是很好,该项目是我添加到其他人工作中的项目。

我正在尝试创建一个可重用的组件,它是一个按钮:

作为一个可重用的组件,我们将传递函数以在按下时调用。

这样做的原因是完成工作的功能可能需要一些时间才能完成,我们想让用户知道在完成之前无法再次按下按钮。

此按钮将替换应用程序中现有的普通按钮。我有一个组件正在禁用和调用该函数。

但是我遇到“无法对未安装的组件执行 React 状态更新”。

当按钮充当提交并且在“工作”完成之前导航到新页面时会发生这种情况。

Igor Soloydenko 对此问题的回答解决了反应状态更新 -无法在未安装的组件上执行反应状态更新

我在试图将这段代码转换成某种可重用的组件时迷失了方向。

我得到的现有代码没有实现下面的 Igor 代码。我怎样才能让这个或类似的工作类似于 Igor ?

类 BaseButton:

import React from 'react';
export default class BaseButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      // You can set the button to be disabled initially.
      disabled: props.disabled,
      // This function that is called.
      customOnPress: props.onPress,
     };
  }
  /**
   * Used to disable button when clicked.
   */
  onPressWrapper = async () => {
    // Disabled.
    if (this.state.disabled) return;
    this.setState({ disabled: true });
    if (this.state.customOnPress != null) {
      await this.state.customOnPress();
    }
    this.setState({ disabled: false });
  };

  // If the handler needs to be replaced without a parent re-render.
  setNewOnPress = async (inPress) => (this.state.customOnPress = inPress);
  // Disable without re-render from parent.
  setDisabled = async (isDisabled) => (this.state.disabled = isDisabled);
}

类 ButtonWithDisable:

import React from 'react';
import BaseButton from './BaseButton';
import { Fa, InputHolder, Text, TextInput } from './ButtonStyles';

class ButtonWithDisable extends BaseButton {
  constructor(props) {
    super(props);
  }
  render() {
    this.props.onPress = () => this.onPressWrapper();
    return (
      <InputHolder {...this.props} disabled={this.state.disabled}>
        <TextInput {...this.props}>
          {this.props.fa ? <Fa name={this.props.fa} {...this.props} children={undefined} /> : null}
          {this.props.icon ? this.props.icon : null}
          <Text {...this.props}>{this.props.children}</Text>
        </TextInput>
      </InputHolder>
    );
  }
}
export default ButtonWithDisable;

示例用法:

<ButtonWithDisable primary fa="check" small onPress={this.onSubmit}>
Submit
</ButtonWithDisable>

标签: javascriptreact-native

解决方案


嗨,安德鲁,我在snack世博会上写了代码,你可以通过这个链接查看

import * as React from 'react';
import {Text, View, StyleSheet, TouchableOpacity} from 'react-native';
import Constants from 'expo-constants';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import {Card} from 'react-native-paper';

export default function App() {
  const [disable, setDisable] = React.useState(false);
  const handleLogic = () => {
    setDisable(true);
    setTimeout(() => {
      //do some work
      setDisable(false);
    }, 3000);
  };
  return (
    <View style={styles.container}>
      <TouchableOpacity
        onPress={() => {
          handleLogic();
        }}
        disabled={disable}
        style={{
          padding: 10,
          backgroundColor: disable ? '#fff' : 'tomato',
          justifyContent: 'center',
          alignItems: 'center',
        }}>
        <Text>Press ME</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

推荐阅读