React:将数组绑定到动态添加的字段
React: Binding array to dynamically added fields
假设我有一个 class 和一个状态级数组
ElementsClass = React.createClass({
getInitialState: function() {
return {
elements: []
}
},
addElement: function() {
var element = {
name: ""
};
},
render() {
return (
{this.state.elements.map(function (element, i) {
return <input value={element.name} />
}
)}
)
}
我的想法是我可以动态地添加到元素数组并出现一个新的输入字段。
如何绑定数据以便能够更改输入字段中的值并自动反映在元素数组中的正确元素中?
要将您的输入与状态数组动态同步,您可以使用 react-catalyst 包中名为 linkState
的东西。使用 npm 安装后,您可以按以下方式使用它:
//need to import
import Catalyst from 'react-catalyst';
ElementsClass = React.createClass({
// mixin the linkedstate component
mixins : [Catalyst.LinkedStateMixin],
getInitialState: function() {
return {
elements: []
}
},
addElement: function() {
var element = {
name: ""
};
//add to elements array
this.state.elements.push(element);
//let react know to rerender necessary parts
this.setState({
elements : this.state.elements
});
},
render() {
return (
{this.state.elements.map(function (element, i) {
//use the linkState method
return <input valueLink={this.linkState('elements.'+i+'.name')} />
}
)}
)
}
我们需要 react-catalyst
包的原因是原生 React 的 valueLink
只会 link 顶级状态项,在你的情况下 elements
。显然这不是特别有用,但幸运的是这是一个相当容易解决的问题。
注意:对于像您的元素输入这样的迭代项,您需要提供一个唯一键。类似于以下内容(可能需要修改得更具体):
{this.state.elements.map(function (element, i) {
//use the linkState method
return <input valueLink={this.linkState('elements.'+i+'.name')} key={'elinput' + i} />
}
)}
这对您的应用没有任何外在影响,主要是为了帮助在内部对元素做出反应。
如果你只想使用 ES5 和 React 来做到这一点,一种解决方案是:
var ElementsClass = React.createClass({
getInitialState: function() {
return {
elements: []
}
},
createElement: function(){
var element = {
name: ''
};
this.setState({elements: this.state.elements.concat(element)});
},
updateElement: function(pos, event) {
var value = event.target.value;
var updatedElements = this.state.elements.map(function(element, i){
if (i === pos){
return {name: value};
}
return element;
});
this.setState({elements: updatedElements});
},
render: function() {
console.log(this.state.elements);
return (
<div>
{this.state.elements.map(function (element, i) {
var boundClick = this.updateElement.bind(this, i);
return <input key={i} onKeyUp={boundClick}/>
}.bind(this))}
<button onClick={this.createElement}>Add Element</button>
</div>
)
}
});
React.render(<ElementsClass />, document.getElementById('app'));
您想将组件状态视为不可变的,因此您不想调用像推送元素这样的变异方法。
使用自定义链接包可以轻松处理这些情况。
State and Forms in React, Part 3: Handling the Complex State
import Link from 'valuelink';
// linked inputs will be deprecated, thus we need to use custom wrappers
import { Input } from 'valueLink/tags.jsx'
const ElementsClass = React.createClass({
getInitialState: function() {
return {
elements: []
}
},
render() {
// Take link to the element
const elementsLink = Link.state( this, 'elements' );
return (
<div>
{ elementsLink.map( ( elementLink, i ) => (
<Input key={ i } valueLink={ elementLink.at( 'name' ) } />
))}
<button onClick={ elementsLink.push({ name : '' })}>
Add Elements
</button>
</div>
);
}
});
假设我有一个 class 和一个状态级数组
ElementsClass = React.createClass({
getInitialState: function() {
return {
elements: []
}
},
addElement: function() {
var element = {
name: ""
};
},
render() {
return (
{this.state.elements.map(function (element, i) {
return <input value={element.name} />
}
)}
)
}
我的想法是我可以动态地添加到元素数组并出现一个新的输入字段。
如何绑定数据以便能够更改输入字段中的值并自动反映在元素数组中的正确元素中?
要将您的输入与状态数组动态同步,您可以使用 react-catalyst 包中名为 linkState
的东西。使用 npm 安装后,您可以按以下方式使用它:
//need to import
import Catalyst from 'react-catalyst';
ElementsClass = React.createClass({
// mixin the linkedstate component
mixins : [Catalyst.LinkedStateMixin],
getInitialState: function() {
return {
elements: []
}
},
addElement: function() {
var element = {
name: ""
};
//add to elements array
this.state.elements.push(element);
//let react know to rerender necessary parts
this.setState({
elements : this.state.elements
});
},
render() {
return (
{this.state.elements.map(function (element, i) {
//use the linkState method
return <input valueLink={this.linkState('elements.'+i+'.name')} />
}
)}
)
}
我们需要 react-catalyst
包的原因是原生 React 的 valueLink
只会 link 顶级状态项,在你的情况下 elements
。显然这不是特别有用,但幸运的是这是一个相当容易解决的问题。
注意:对于像您的元素输入这样的迭代项,您需要提供一个唯一键。类似于以下内容(可能需要修改得更具体):
{this.state.elements.map(function (element, i) {
//use the linkState method
return <input valueLink={this.linkState('elements.'+i+'.name')} key={'elinput' + i} />
}
)}
这对您的应用没有任何外在影响,主要是为了帮助在内部对元素做出反应。
如果你只想使用 ES5 和 React 来做到这一点,一种解决方案是:
var ElementsClass = React.createClass({
getInitialState: function() {
return {
elements: []
}
},
createElement: function(){
var element = {
name: ''
};
this.setState({elements: this.state.elements.concat(element)});
},
updateElement: function(pos, event) {
var value = event.target.value;
var updatedElements = this.state.elements.map(function(element, i){
if (i === pos){
return {name: value};
}
return element;
});
this.setState({elements: updatedElements});
},
render: function() {
console.log(this.state.elements);
return (
<div>
{this.state.elements.map(function (element, i) {
var boundClick = this.updateElement.bind(this, i);
return <input key={i} onKeyUp={boundClick}/>
}.bind(this))}
<button onClick={this.createElement}>Add Element</button>
</div>
)
}
});
React.render(<ElementsClass />, document.getElementById('app'));
您想将组件状态视为不可变的,因此您不想调用像推送元素这样的变异方法。
使用自定义链接包可以轻松处理这些情况。
State and Forms in React, Part 3: Handling the Complex State
import Link from 'valuelink';
// linked inputs will be deprecated, thus we need to use custom wrappers
import { Input } from 'valueLink/tags.jsx'
const ElementsClass = React.createClass({
getInitialState: function() {
return {
elements: []
}
},
render() {
// Take link to the element
const elementsLink = Link.state( this, 'elements' );
return (
<div>
{ elementsLink.map( ( elementLink, i ) => (
<Input key={ i } valueLink={ elementLink.at( 'name' ) } />
))}
<button onClick={ elementsLink.push({ name : '' })}>
Add Elements
</button>
</div>
);
}
});