2016-07-09 20 views
4

Ich bin der usage with React Redux-Tutorial folgen. Etwas, das ich wirklich nicht verstehe, ist, wie man Benutzereingaben abruft.React/Redux, wie Benutzereingaben

Sie bauen einen FilterLink Behälter, dessen mapDispatchToProps ist

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
    onClick:() => { 
     dispatch(setVisibilityFilter(ownProps.filter)) 
    } 
    } 
} 

So spritzt er seine ownProps.filter an die angeschlossenen Präsentations-Komponente. Wenn wir gehen und sehen, wie dieser Container konstruiert wird

const Footer =() => (
    <p> 
    Show:{" "} 
    <FilterLink filter="SHOW_ALL">All</FilterLink>{", "} 
    <FilterLink filter="SHOW_ACTIVE">Active</FilterLink>{", "} 
    <FilterLink filter="SHOW_COMPLETED">Completed</FilterLink> 
    </p> 
) 

Ok, gibt es die "Filter" -Eigenschaft. Das ist klar.

Jetzt möchte ich einen Textfilter für das gleiche Beispiel erstellen. Also zuerst hier ist meine Präsentations-Komponente

const TodoSearch = ({onSubmit}) => (
    <form 
     onSubmit={e => { 
      e.preventDefault() 
      onSubmit() 
     }} 
    > 
     <input placeholder="Text search" /> 
     <input type="submit" value="Go" /> 
    </form> 
) 

Aber wenn ich komme, um den Behälter zu schreiben, weiß ich nicht, wie Benutzereingaben

const mapDispatchToProps = (dispatch) => { 
    return { 
     onSubmit:() => { 
      dispatch(setTextSearch(????)) 
     } 
    } 
} 

Es ist etwas zu bekommen, ich mit jQuery $ (# text tun würde) .val() aber ... ist es der beste Weg?

Später auf dem gleichen Tutorial bauen sie ein kleines Formular, um eine Todo zu der Liste hinzuzufügen. Ok, lass uns gehen und sehen, wie sie dann Input fangen.

let AddTodo = ({ dispatch }) => { 
    let input 

    return (
     <div> 
      <form onSubmit={e => { 
       e.preventDefault() 
       if (!input.value.trim()) { 
        return 
       } 
       dispatch(addTodo(input.value)) 
       input.value = '' 
      }}> 
       <input ref={node => { 
        input = node 
       }} /> 
       <button type="submit"> 
        Add Todo 
       </button> 
      </form> 
     </div> 
    ) 
} 

Warten Sie, wo ist die Magie hier? Haben sie mit diesem Ref-Trick Wert in "Eingabe" -Variablen gebracht? Ist das korrekt? Also, wenn es 20 Eingabefelder gibt, muss ich 20 Variablen mit 20 verschiedenen Referenzen verwenden?

Jede Hilfe schätzen, danke

+0

Ich glaube, es ist ein Problem der Reaktion, anstatt Redux. Und es ist gut erklärt in https://reactjs.org/docs/forms.html#controlled-components. –

Antwort

2

Ändern Sie Ihre Sendefunktion wie folgt. Auch

const mapDispatchToProps = (dispatch) => { 
    return { 
     onSubmit: (evt) => { 
      dispatch(setTextSearch(evt.target.querySelector('input').value) 
     } 
    } 
} 

,

const TodoSearch = ({onSubmit}) => (
    <form 
     onSubmit={e => { 
      e.preventDefault() 
      onSubmit(e) 
     }} 
    > 
     <input placeholder="Text search" /> 
     <input type="submit" value="Go" /> 
    </form> 
) 
+0

Ich arbeite nicht, "evt" ist zu diesem Zeitpunkt immer undefiniert. Vielleicht, weil dies eine Container-Komponente und keine Presentational-Komponente ist? – user2029958

+0

Ich habe es bearbeitet. Probieren Sie es jetzt. – garajo

+0

Es funktioniert, danke – user2029958

0

Dieses Beispiel hier ist, dass Sie besser verstehen zu lassen, die reagieren-redux Art und Weise, Dinge zu tun typische reagieren-redux, wie eine Komponente anschließen. Es ist kein Tutorial, um zu lernen, wie man den Eingabezustand verwaltet.

So verwenden sie zum Beispiel das ref Attribut, um der input Variable den <input/> DOM-Knoten zuzuweisen. Dann ist der Wert dieses Eingangs-DOM-Knotens über input.value zugänglich.

Sie verwenden, was eine Uncontrolled Component genannt wird, d. H. Eine Komponente, die ihren Zustand intern behandelt. Es ist praktisch, wenn Sie sich nicht mit komplexer Form befassen müssen und wenn der Wert dieser speziellen Komponente nicht für andere Zwecke gedacht ist.

Aber sagen wir jetzt, dass dieser Todo-Item-Text zum Beispiel auf dem Server gespeichert werden muss. Der Wert dieser Eingabe soll jetzt an anderer Stelle verwendet werden, in diesem Fall wahrscheinlich in einem Aktionsersteller, der die POST-Anforderung behandelt. In diesem Fall wird der Wert des Formulars in Ihrem redux Speicher enthalten, und Sie sind jetzt mit Controlled Component

3

Umgang Wenn Sie den Benutzer Eingang erhalten möchten, können Sie etwas tun können:

Diese Demo SearchForm Komponente rendert ein Eingabefeld und eine Schaltfläche, um die Aktion auszulösen.

import React, { Component, PropTypes } from 'react' 

export default class SearchForm extends Component { 
    constructor(props) { 
    super(props) 
    this.handleGoClick = this.handleGoClick.bind(this) 
    } 

    getInputValue() { 
    return this.refs.input.value 
    } 

    handleGoClick() { 
    this.props.onChange(this.getInputValue()) 
    } 

    render() { 
    return (
     <div> 
     <input ref='input' /> 
     <button onClick={this.handleGoClick}>Go</button> 
     </div> 
    ) 
    } 
} 

bemerken, dass das Eingabefeld ein ref Wert hat.Sie können den aktuellen Wert mit this.refs.input.value abrufen. Die Methode übergibt diesen Wert dann an einen Aktionsersteller (der über mapDispatchToProps an die Requisiten der Komponente übergeben wurde).

+0

Ist das nicht Breaking Redux Philosophie? Sollte ich die Eingabe (ob sie den Zustand der App aktualisiere oder nicht) nicht in der Container-Komponente (mapDispatchToProps), sondern in einem Präsentations-Component abrufen, da es sich um Ihr Suchformular handelt? – user2029958

+0

Persönlich glaube ich nicht, dass es Redux-Philosophie bricht: (1) Single Quelle der Wahrheit (2) State ist schreibgeschützt (3) Änderungen werden mit reinen Funktionen vorgenommen. Siehe [Drei Prinzipien] (http://redux.js.org/docs/introduction/ThreePrinciples.html). Vielleicht hat jemand anderes eine Meinung dazu? – Steve

+0

Ich glaube, es hat die erste Regel gebrochen. Wie in https://reactjs.org/docs/uncontrolled-components.html erwähnt, behält eine unkontrollierte Komponente die Quelle der Wahrheit im DOM. –

1

Ich benutze ref den Wert des Eingangs zu bekommen, die handleSubmit() -Methode in der Klasse, so dass es Eingang durch ref erhalten. Wenn Sie die Dispatch-Methode verwenden möchten, ordnen Sie einfach eine Prop in mapDispatchToProps() zu.

class AddTodo extends Component { 

    handleSubmit(event) { 
     let input = this.refs.input; 
     event.preventDefault(); 
     if (!input.value.trim()) { 
      return 
     } 
     this.props.addTodo(input.value); 
     input.value = '' 
    } 

    render() { 
     return (
      <div> 
       <form onSubmit={this.handleSubmit.bind(this)}> 
        <input ref="input"/> 
        <button type="submit"> 
         Add Todo 
        </button> 
       </form> 
      </div> 
     ); 
    } 

} 

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
     addTodo:(text) => { 

      dispatch(addTodo(text)); 
     } 
    } 
}; 

export default connect(null, mapDispatchToProps)(AddTodo); 
+0

Es wäre toll, wenn Sie eine Erklärung hinzufügen könnten, wie/warum Ihr Code funktioniert –