0

Ich rendere eine Liste von Eingaben und ich möchte den Wert jedes Inputs an den Verweis einer Verbindung binden. Mein aktueller Versuch macht https://twitter.com/intent/tweet?text=undefined:In React, wie ein Input-Wert beim Rendern einer Liste von Eingaben zu binden?

class App extends React.Component { 
    tweets = [ 
    { id: 1, link: 'example.com' }, 
    { id: 2, link: 'example2.com' } 
    ]; 

    render() { 
    return (
     <div> 
     {this.tweets.map(tweet => 
      <div key={tweet.id}> 
      <input type="text" placeholder="text" onChange={e => tweet.text = e.target.value} /> 
      <a href={`https://twitter.com/intent/tweet?text=${tweet.text}`}>Tweet</a> 
      </div> 
     )} 
     </div> 
    ); 
    } 
} 

Dies muss wohl setState einzubeziehen, aber ich habe keine Ahnung, wie das zu erreichen, wenn eine Liste zu machen. Ich habe versucht, etwas darüber zu recherchieren, habe aber nichts hilfreiches gefunden.

JSFiddle: https://jsfiddle.net/nunoarruda/u5c21wj9/3/

Irgendwelche Ideen?

+0

Sie müssen den Text von der Eingabe im Status speichern (mit SetState), nicht im Tweets-Array. Dann kannst du es mit etwas wie {this.state.tweetsText [tweet.id]} rendern. –

Antwort

1

Sie können die Tweets Variable auf den Zustand bewegen Konsistenz in diesem Array zu halten.

class App extends React.Component { 
 
    constructor(props) { 
 
    \t super(props) 
 
    this.state = { 
 
    \t tweets: [ 
 
     \t { id: 1, link: 'example.com' }, 
 
     \t { id: 2, link: 'example2.com' } 
 
     ] 
 
    }; 
 
    }; 
 
    
 
    setTweets = index => e => { 
 
    \t const { tweets } = this.state 
 
    tweets[index].text = e.target.value 
 
    this.setState({ tweets }) 
 
    } 
 

 
    render() { 
 
    \t const { tweets } = this.state 
 
    return (
 
     <div> 
 
     {tweets.map((tweet, index) => 
 
      <div key={tweet.id}> 
 
      <input type="text" placeholder="text" onChange={this.setTweets(index)} /> 
 
      <a href={`https://twitter.com/intent/tweet?text=${tweet.text}`}>Tweet</a> 
 
      </div> 
 
     )} 
 
     </div> 
 
    ); 
 
    } 
 
}

Aktualisiert Jsfiddle: https://jsfiddle.net/u5c21wj9/6/

+0

Großartig, genau das, was ich wollte. Kannst du 'index => e =>' erklären? Wie kommt es, dass das Event-Objekt 'e' an' setTweets' übergeben wird, wenn es nicht in 'onChange' referenziert wird? – nunoarruda

-3

Links Informationen ist in der link Eigenschaft Ihres Tweets-Array. Die Eigenschaft text ist nicht definiert. Also, Ihre Funktion wie diese

render() { 
    return (
     <div> 
     {this.tweets.map(tweet => 
      <div key={tweet.id}> 
      <input type="text" placeholder="text" onChange={e => tweet.text= e.target.value} /> 
      <a href={`https://twitter.com/intent/tweet?text=${tweet.link}`}>Tweet</a> 
      </div> 
     )} 
     </div> 
    ); 
    } 
+0

Danke, dass du versucht hast zu helfen, aber das ist nicht das, was ich versuche zu erreichen. Die Texteigenschaft ist anfangs nicht gesetzt, da sie manuell vom Benutzer in die Eingabe eingegeben wird: onChange = {e => tweet.text = e.target.value} – nunoarruda

1

Sie das gewünschte Ergebnis erreichen können mit state aussehen machen sollte.

return (
    <div> 
    {tweets.map(({ id, link }) => 
     <div key={id}> 
     <input type="text" placeholder="text" onChange={({ target }) => this.setState({ [id]: target.value })} /> 
     <a href={`https://twitter.com/intent/tweet?text=${this.state[id] || link}`}>Tweet</a> 
     </div> 
    )} 
    </div> 
); 

Hinweis: Ich würde tweets außerhalb der Komponente bewegen und einige ES6 Funktionen implementieren.

Aktualisiert Jsfiddle: https://jsfiddle.net/u5c21wj9/7/

0

Sie sollten wirklich einen Zustand hier verwenden und machen Sie Ihre tweets variable Teil davon sein. Um dies zu tun, fügen Sie einen Konstruktor:

constructor() { 
    super(); 
    this.state = { 
    tweets: [ 
     { id: 1, link: 'example.com' }, 
     { id: 2, link: 'example2.com' } 
    ] 
    }; 
} 

Dann müssen Sie jede link mutieren, wenn Sie in einem der Eingänge ein. Es gibt ein paar Tücken hier, mich durch sie so gehen lassen one-by-one:

changeTweet = (id, e) => { 
    let arr = this.state.tweets.slice(); 
    let index = arr.findIndex(i => i.id === id); 
    let obj = Object.assign({}, arr[index]); 
    obj.link = e.target.value; 
    arr[index] = obj; 
    this.setState({tweets: arr}); 
} 

Zuerst müssen Sie eine Kopie Ihrer Zustandsvariablen erstellen. Dies gibt Ihnen etwas, mit dem Sie arbeiten können, ohne den Zustand direkt zu verändern, der Anti-Pattern ist. Dies kann mit slice() erfolgen.

Da Sie das id des zu ändernden Objekts senden, müssen wir es in unserem Array finden (falls die Elemente ungeordnet sind). Dies geschieht mit findIndex(). Vielleicht möchten Sie das Szenario behandeln, in dem ein solcher Index nicht gefunden wird (ich habe das nicht getan).

Jetzt wissen wir, wo in dem Array das Objekt mit dem angegebenen id Schlüssel ist. Erstellen Sie nun eine Kopie dieses Objekts (welches ein Objekt ist). Dies soll auch verhindern, dass der Zustand direkt mutiert wird. Tun Sie dies mit Object.assign().

nun die link zum Eingangswert ändern, wie wir in getippt. Ersetzen Sie das alte Item-Objekt mit dem neuen (obj) und den alten tweets Array mit dem neuen (arr) ersetzen.


Hier ist das vollständige Beispiel:

class App extends React.Component {  
 
    constructor() { 
 
    super(); 
 
    \t this.state = { 
 
    \t tweets: [ 
 
     { id: 1, link: 'example.com' }, 
 
     { id: 2, link: 'example2.com' } 
 
     ] 
 
    }; 
 
    } 
 
    
 
    changeTweet = (id, e) => { 
 
    let arr = this.state.tweets.slice(); 
 
    let index = arr.findIndex(i => i.id === id); 
 
    let obj = Object.assign({}, arr[index]); 
 
    obj.link = e.target.value; 
 
    arr[index] = obj; 
 
    \t this.setState({tweets: arr}); 
 
    } 
 

 
    render() { 
 
    return (
 
     <div> 
 
     {this.state.tweets.map(tweet => 
 
      <div key={tweet.id}> 
 
      <input type="text" placeholder="text" onChange={(e) => this.changeTweet(tweet.id, e)} /> 
 
      <a href={`https://twitter.com/intent/tweet?text=${tweet.link}`}>Tweet</a> 
 
      </div> 
 
     )} 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

0

Sie müssen den Text aus dem Eingang in den Zustand (mit setState), nicht in der Tweets Array speichern. Dann können Sie es rendern, den Text vom Staat erhalten.

class App extends React.Component { 
    tweets = [ 
    { id: 1, link: 'example.com' }, 
    { id: 2, link: 'example2.com' } 
    ]; 

    state = { 
    tweetsText :{} 
    } 

    handleTextChange = (event, tweetId) => { 
    const tweetsTextCopy = Object.assign({}, this.state.tweetsText) 
    tweetsTextCopy[tweetId] = event.target.value 
    this.setState({tweetsText: tweetsTextCopy}) 
    } 

    render() { 
    return (
     <div> 
     {this.tweets.map(tweet => 
      <div key={tweet.id}> 
      <input type="text" placeholder="text" onChange={e => this.handleTextChange(e, tweet.id)} /> 
      <a href={`https://twitter.com/intent/tweet?text=${this.state.tweetsText[tweet.id]}`}>Tweet</a> 
      </div> 
     )} 
     </div> 
    ); 
    } 
} 
Verwandte Themen