在 React 中,如何在呈现输入列表时绑定输入的值?
In React, how to bind an input's value when rendering a list of inputs?
我正在呈现输入列表,我想将每个输入的值绑定到 link 的 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>
);
}
}
这可能需要涉及 setState
但我不知道在渲染列表时如何实现。我试图对此进行一些研究,但没有发现任何有用的东西。
JSFiddle:https://jsfiddle.net/nunoarruda/u5c21wj9/3/
有什么想法吗?
链接信息位于推文数组的 link
属性 中。 属性 text
未定义。
所以,你的渲染函数应该是这样的
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>
);
}
您可以使用 state
获得所需的结果。
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
移到组件之外并实现一些 ES6 功能。
已更新 Jsfiddle:https://jsfiddle.net/u5c21wj9/7/
你真的应该在这里使用一个状态,让你的 tweets
变量成为它的一部分。为此,添加一个构造函数:
constructor() {
super();
this.state = {
tweets: [
{ id: 1, link: 'example.com' },
{ id: 2, link: 'example2.com' }
]
};
}
然后您需要在输入其中一个输入时改变每个 link
。这里有一些陷阱,所以让我一一解决:
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()
.
执行此操作
现在将 link
更改为我们输入的输入值。将旧的项目对象替换为新的 (obj
) 并将旧的 tweets
数组替换为新的一 (arr
).
完整示例如下:
class App extends React.Component {
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});
}
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>
您可以将 tweets 变量移动到状态以保持该数组的一致性。
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
tweets: [
{ id: 1, link: 'example.com' },
{ id: 2, link: 'example2.com' }
]
};
};
setTweets = index => e => {
const { tweets } = this.state
tweets[index].text = e.target.value
this.setState({ tweets })
}
render() {
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>
);
}
}
已更新 Jsfiddle:https://jsfiddle.net/u5c21wj9/6/
您需要将输入的文本保存在状态中(使用 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>
);
}
}
我正在呈现输入列表,我想将每个输入的值绑定到 link 的 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>
);
}
}
这可能需要涉及 setState
但我不知道在渲染列表时如何实现。我试图对此进行一些研究,但没有发现任何有用的东西。
JSFiddle:https://jsfiddle.net/nunoarruda/u5c21wj9/3/
有什么想法吗?
链接信息位于推文数组的 link
属性 中。 属性 text
未定义。
所以,你的渲染函数应该是这样的
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>
);
}
您可以使用 state
获得所需的结果。
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
移到组件之外并实现一些 ES6 功能。
已更新 Jsfiddle:https://jsfiddle.net/u5c21wj9/7/
你真的应该在这里使用一个状态,让你的 tweets
变量成为它的一部分。为此,添加一个构造函数:
constructor() {
super();
this.state = {
tweets: [
{ id: 1, link: 'example.com' },
{ id: 2, link: 'example2.com' }
]
};
}
然后您需要在输入其中一个输入时改变每个 link
。这里有一些陷阱,所以让我一一解决:
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()
.
现在将 link
更改为我们输入的输入值。将旧的项目对象替换为新的 (obj
) 并将旧的 tweets
数组替换为新的一 (arr
).
完整示例如下:
class App extends React.Component {
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});
}
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>
您可以将 tweets 变量移动到状态以保持该数组的一致性。
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
tweets: [
{ id: 1, link: 'example.com' },
{ id: 2, link: 'example2.com' }
]
};
};
setTweets = index => e => {
const { tweets } = this.state
tweets[index].text = e.target.value
this.setState({ tweets })
}
render() {
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>
);
}
}
已更新 Jsfiddle:https://jsfiddle.net/u5c21wj9/6/
您需要将输入的文本保存在状态中(使用 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>
);
}
}