React Native onChangeText就像ReactJS中的onChange

时间:2019-08-16 08:24:57

标签: reactjs react-native

我同时学习ReactJS和React Native。我在一个udemy教程中看到了一个非常漂亮的东西,教授将其只是一个onChange方法,对于所有输入并利用“ name”属性,他可以做到这一点:

const onChange = event =>
    setFormData({ ...formData, [event.target.name]: event.target.value });

因此,他说,除了在每个输入内部使用每个不同的onChange之外,我们只能使用一个不同的方法。

这是我正在谈论的代码:

const Register = props => {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    password: '',
    password2: ''
  });

  const { name, email, password, password2 } = formData;
  const onChange = event =>
    setFormData({ ...formData, [event.target.name]: event.target.value });

  const onSubmit = async event => {
    event.preventDefault();
    if (password !== password2) {
      props.setAlert('Passwords do not match', 'danger', 5000);
    } else {
      props.registerUser({ name, email, password });
    }
  };


  if (props.isAuthenticated) {
    return <Redirect to="/dashboard" />;
  }
  return (
    <Fragment>
      <h1 className="large text-primary">Sign Up</h1>
      <p className="lead">
        <i className="fas fa-user" /> Create Your Account
      </p>
      <form className="form" onSubmit={event => onSubmit(event)}>
        <div className="form-group">
          <input
            type="text"
            placeholder="Name"
            name="name"
            value={name}
            onChange={event => onChange(event)}
          />
        </div>
        <div className="form-group">
          <input
            type="email"
            placeholder="Email Address"
            name="email"
            value={email}
            onChange={event => onChange(event)}
          />
          <small className="form-text">
            This site uses Gravatar so if you want a profile image, use a
            Gravatar email
          </small>
        </div>
        <div className="form-group">
          <input
            type="password"
            placeholder="Password"
            name="password"
            // minLength="6"
            value={password}
            onChange={event => onChange(event)}
          />
        </div>
        <div className="form-group">
          <input
            type="password"
            placeholder="Confirm Password"
            name="password2"
            value={password2}
            onChange={event => onChange(event)}
          />
        </div>
        <input type="submit" className="btn btn-primary" value="Register" />
      </form>
      <p className="my-1">
        Already have an account? <Link to="/login">Sign In</Link>
      </p>
    </Fragment>
  );
};

在React Native中,那是另一位教授,我试图思考如何做到这一点。我尝试了几天TextInput提供的道具,但是在我看来,没有一种可以用来在ReactJS中使用“ name”属性。

这是React Native应用程序的代码:

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Button,
  TextInput,
} from 'react-native';

class PlaceInput extends Component {
  state = {
    userName: '',
    placeName: ''
  }

  userNameChangeHandler = (value) => {
    this.setState({ userName: value })
  }

  placeNameChangeHandler = (value) => {
    this.setState({ placeName: value })
  }

  placeSubmitHandler = () => {
    if (this.state.placeName.trim() === '') {
      return;
    }

    this.props.onPlaceAdded(this.state.placeName)
  }

  render() {
    return (
      <View style={styles.inputContainer}>
        <TextInput
          style={styles.placeInput}
          value={this.state.userName}
          onChangeText={this.userNameChangeHandler}
          placeholder='User Name' />
        <TextInput
          style={styles.placeInput}
          value={this.state.placeName}
          onChangeText={this.placeNameChangeHandler}
          placeholder='Beautiful place' />
        <Button title='Add' style={styles.placeButton} onPress={this.placeSubmitHandler} />
      </View>
    );
  }
};

请有人帮我理解:React Native中可能有一个onChangeText方法,就像ReactJS的教授对onChange所做的那样?

3 个答案:

答案 0 :(得分:2)

尝试将输入“名称”作为值传递给处理程序函数。 像这样:

import React, { Component } from 'react';
import {
  StyleSheet, View, TextInput,
} from 'react-native';

class PlaceInput extends Component {
  state = {
    userName: '',
    placeName: ''
  }

  handleInputChange = (inputName, inputValue) => {
    this.setState(state => ({ 
      ...state,
      [inputName]: inputValue // <-- Put square brackets
    }))
  }

  render () {
    return (
      <View style={styles.inputContainer}>
        <TextInput
          style={styles.placeInput}
          value={this.state.userName}
          onChangeText={value => this.handleInputChange('userName', value)}
          placeholder='User Name' />
        <TextInput
          style={styles.placeInput}
          value={this.state.placeName}
          onChangeText={value => this.handleInputChange('placeName', value)}
          placeholder='Beautiful place' />
      </View>
    );
  }
};

答案 1 :(得分:1)

对于该类型的函数,您使用的是错误的道具。尽管onChangeText很好,但它会将带有单个参数的函数作为其参数:更改后的文本。因此,您无法使用onChangeText来做到这一点。

但是,存在另一个名为onChange的道具。根据文档,此文档提供了以下对象作为参数:{ nativeEvent: { eventCount, target, text} }。虽然可以使用,但这里的目标只是一个数字。

我有什么建议?

将您的函数改为采用第二个参数:event.target.name,而不是尝试通过name处理它。之后,您应该按以下方式调用函数;

onChangeText={text => this.inputChangeHandler(text, 'name')}

这将创建一个函数,其唯一目的是提供第二个参数,从而允许您仅对所有文本更改使用一个函数。

答案 2 :(得分:0)

您需要对按钮以外的组件使用TouchableOpacity

  "$schema-template": "2.0.0",
  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.0",
        "runtime": {
          "type": "docker",
          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {
              "myRegistryName": {
                "username": "$CONTAINER_REGISTRY_USERNAME",
                "password": "$CONTAINER_REGISTRY_PASSWORD",
                "address": "myRegistryAddress.azurecr.io"
              }
            }
          }
        },
        "systemModules": {
          "edgeAgent": {
            "type": "docker",
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-agent:1.0",
              "createOptions": {}
            }
          },
          "edgeHub": {
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-hub:1.0",
              "createOptions": {
                "HostConfig": {
                  "PortBindings": {
                    "5671/tcp": [
                      {
                        "HostPort": "5671"
                      }
                    ],
                    "8883/tcp": [
                      {
                        "HostPort": "8883"
                      }
                    ],
                    "443/tcp": [
                      {
                        "HostPort": "443"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "modules": {
          "Module_Name": {
            "version": "1.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "${MODULES.Module_Name}",
              "createOptions": {}
            },
            "env": {
              "test_var": {
                "value": "secret"
              }
            }
          }
        }
      }
    },
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.0",
        "routes": {
          "route": "FROM /messages/* INTO $upstream"
        },
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 7200
        }
      }
    }
  }
}