簡體   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