繁体   English   中英

使用无状态组件实现表单输入验证的正确方法是什么

[英]What is the proper way of implementing form input validation with stateless components

所以我最近开始使用 react-native,显然我想使用最佳实践来处理我的应用程序。 这就是为什么我决定使用 redux 并按照建议编写无状态的功能组件。

一旦我习惯了它并建立了一些标准,它就工作了一段时间:我编写了一个功能组件,映射状态并调度到它的道具,并有一个存储跟踪事物是如何被Provider注入的。

一旦我开始验证我的表单输入组件,事情就变得复杂了。 假设我想要一个组件,它可以验证其输入并在出现问题时显示错误。 我显然可以为此向我的全局存储添加一些状态,但我不想在我的全局存储中为我在应用程序中使用的每个输入都有一个位置。 这可能与关于使用 redux 的教导相反,但我有一种感觉,我想要的并不是那么不切实际。

所以举一个我想要的例子:

const Input = ({ error }) => {
  let style = styles.input;
  const onChange = (val) => {
    // change the error here, say
    if(val === 'test') error = null;
    else error = 'must be test';
  };
  if (error) {
    style = styles.inputError;
  }
  return (
    <TextInput
      style={style}
      onChangeText={onChange}
    />
  );
};

但我不想将错误连接到全局状态。

这问的太多了,还是我忽略了使Input刷新本身的方法(我根本无法将this放入)?

我知道这更像是一个哲学问题,因为为您的组件创建 ES6 类并使用setState有一个明显的解决方案。 我最感兴趣的是听到一些解决这个问题的方法,如果有问题,或者我太固执了。 :)

好吧,我提到这几乎是一个元问题,但对我来说是一个重要的问题,因为我在摆弄它的过程中学到了很多东西。

希望我学到的东西能帮助遇到同样问题的人,并节省他用很少的在线资源研究这个主题所需的时间:

  1. 你不能也可能不应该能够从它内部访问你的纯控制。
  2. 如果您确实必须将控件创建为 ES6 类并访问this ,即使您的 linter 也不会再抱怨,因为这是很好的用例,因此在某些情况下可以扩展Component

使用这两个结论的控件示例如下所示:

class Input extends Component {
  render() {
    let style = styles.input;
    const error = this.state && this.state.error;
    const onChange = (val) => {
      if (val === 'test') this.setState({ error: null });
      else this.setState({ error: 'test required' });
    };
    if (error) {
      style = styles.inputError;
    }
    return (
      <TextInput
        style={style}
        onChangeText={onChange}
      />
    );
  }
}

现在,由于我很顽固,我又学到了一件事:可以只用纯组件来制作它。 就像我在某处的评论中所说的那样,可以创建一个本地存储,将您的组件包装在Provider并以您在使用功能组件时习惯的方式连接到它。 我不确定它会有多大用处,但我会提供示例:

const localStore = createStore(
  (state = [], obj) => (obj ? { errorMessage: obj.error } : state),
  { errorMessage: null },
);

const inputWithStore = ({ error }) => {
  let style = styles.input;
  const onChange = (val) => {
    if (val === 'test') localStore.dispatch({ type: 'unused', error: null });
    else localStore.dispatch({ type: 'unused', error: 'test required' });
  };
  if (error) {
    style = styles.inputError;
  }
  return (
    <TextInput
      style={style}
      onChangeText={onChange}
    />
  );
};

const mapStateToProps = (state) => ({ error: state.errorMessage });

const InputWithStore = connect(mapStateToProps)(inputWithStore);

const Input = () =>
(
  <Provider store={localStore}>
    <InputWithStore />
  </Provider>
);

我仍然会很高兴听到有关这些的其他方法和评论。 谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM