Javascript 在React中,如何绑定输入';呈现输入列表时的s值?

Javascript 在React中,如何绑定输入';呈现输入列表时的s值?,javascript,reactjs,ecmascript-6,setstate,array.prototype.map,Javascript,Reactjs,Ecmascript 6,Setstate,Array.prototype.map,我正在呈现一个输入列表,我想将每个输入的值绑定到链接的href。我当前的尝试呈现https://twitter.com/intent/tweet?text=undefined: class App extends React.Component { tweets = [ { id: 1, link: 'example.com' }, { id: 2, link: 'example2.com' } ]; render() { return ( &l

我正在呈现一个输入列表,我想将每个输入的值绑定到链接的href。我当前的尝试呈现
https://twitter.com/intent/tweet?text=undefined

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>
    );
  }
}
类应用程序扩展了React.Component{
推特=[
{id:1,链接:'example.com'},
{id:2,链接:'example2.com'}
];
render(){
返回(
{this.tweets.map(tweet=>
tweet.text=e.target.value}/>
)}
);
}
}
这可能需要涉及
setState
,但我不知道在呈现列表时如何实现这一点。我试着对此做一些研究,但没有发现任何有用的东西

JSFiddle:


有什么想法吗?

链接信息位于tweets数组的
link
属性中。未定义属性
文本
。 因此,渲染函数应该如下所示

  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>
    );
  }
render(){
返回(
{this.tweets.map(tweet=>
tweet.text=e.target.value}/>
)}
);
}

您可以使用
状态
达到所需的结果

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>
);
返回(
{tweets.map({id,link})=>
this.setState({[id]:target.value})}/>
)}
);
注意:我会将
推文
移到组件之外,并实现一些ES6功能


更新的JSFIDLE:

您真的应该在此处使用状态,并使您的
tweets
变量成为其中的一部分。为此,请添加一个构造函数:

constructor() {
  super();
  this.state = {
    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;
  this.setState({tweets: arr});
}
首先,您需要创建状态变量的副本。这给了您一些可以处理的东西,而不需要直接改变反模式的状态。这可以通过
slice()
完成

由于您正在发送要修改的对象的
id
,因此我们需要在数组中找到它(以防项目无序)。这是通过
findIndex()
完成的。您可能希望处理找不到此类索引的场景(我没有这样做)

现在我们知道了具有给定
id
键的对象在数组中的位置。现在,创建该项(对象)的副本。这也是为了防止直接改变状态。使用
Object.assign()
执行此操作

现在将
链接更改为我们输入的输入值。用新的(
obj
)替换旧的item对象,并用新的(
arr
)替换旧的
tweets
数组


以下是完整的示例:

类应用程序扩展了React.Component{
构造函数(){
超级();
此.state={
推特:[
{id:1,链接:'example.com'},
{id:2,链接:'example2.com'}
]
};
}
changeTweet=(id,e)=>{
设arr=this.state.tweets.slice();
让index=arr.findIndex(i=>i.id==id);
设obj=Object.assign({},arr[index]);
obj.link=e.target.value;
arr[index]=obj;
this.setState({tweets:arr});
}
render(){
返回(
{this.state.tweets.map(tweet=>
this.changeTweet(tweet.id,e)}/>
)}
);
}
}
ReactDOM.render(,document.getElementById('root'))

您可以将tweets变量移动到状态,以保持该数组中的一致性

类应用程序扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
推特:[
{id:1,链接:'example.com'},
{id:2,链接:'example2.com'}
]
};
};
setTweets=index=>e=>{
const{tweets}=this.state
tweets[index].text=e.target.value
this.setState({tweets})
}
render(){
const{tweets}=this.state
返回(
{tweets.map((tweet,index)=>
)}
);
}

}
您需要将输入的文本保存在状态(使用setState),而不是tweets数组中。然后,您可以从状态获取文本来渲染它

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>
    );
  }
}
类应用程序扩展了React.Component{
推特=[
{id:1,链接:'example.com'},
{id:2,链接:'example2.com'}
];
状态={
tweetsText:{}
}
handleTextChange=(事件,tweetId)=>{
const tweetsTextCopy=Object.assign({},this.state.tweetsText)
tweetsTextCopy[tweetId]=event.target.value
this.setState({tweetsText:tweetsTextCopy})
}
render(){
返回(
{this.tweets.map(tweet=>
this.handleTextChange(e,tweet.id)}/>
)}
);
}
}

您需要将输入的文本保存在状态(使用setState),而不是tweets数组中。然后你可以用类似{this.state.tweetsText[tweet.id]}的东西来渲染它。谢谢你的帮助,但这不是我想要实现的。文本属性最初是未设置的,因为它将由用户在输入中手动输入:onChange={e=>tweet.text=e.target.value}很好,这正是我想要的。你能解释一下吗?如果事件对象
e
未在
onChange
中引用,那么它为什么会被传递到
setTweets