Javascript 将setState()绑定到全局函数只影响组件的一个实例
注意:根据尼古拉斯·托尔的回答,我对问题进行了修改后,对问题进行了编辑。 我有一个全局函数,它绑定到一个组件并改变它的状态。 我想建立一个表单生成器系统。有一个名为Javascript 将setState()绑定到全局函数只影响组件的一个实例,javascript,reactjs,Javascript,Reactjs,注意:根据尼古拉斯·托尔的回答,我对问题进行了修改后,对问题进行了编辑。 我有一个全局函数,它绑定到一个组件并改变它的状态。 我想建立一个表单生成器系统。有一个名为setLabel的全局函数,它绑定到名为InputBox的组件并更改其状态。此全局函数通过另一个名为ModalPanel的组件触发,该组件控制绑定组件InputBox上的可编辑属性。为了简化这个问题,我简化了函数和组件类 以下是全局函数: function setLabel(postID, attributeName ){
setLabel
的全局函数,它绑定到名为InputBox
的组件并更改其状态。此全局函数通过另一个名为ModalPanel
的组件触发,该组件控制绑定组件InputBox
上的可编辑属性。为了简化这个问题,我简化了函数和组件类
以下是全局函数:
function setLabel(postID, attributeName ){
var text = 'example';
if(text !== ''){
this.setState({ [attributeName] : text});
}
}
下面是绑定到setLabel
函数的组件。注意setLabel
函数是如何作为属性从父InputBox
组件传递到子ModalPanel
组件函数的
class InputBox extends Component{
constructor(props){
super(props);
this.state = {
placeholder : '',
maxlength: '',
type: '',
}
this.setLabel = setLabel.bind(this); // Binding this to the global function.
}
render(){
let elementId = "inputElement-" + this.props.idCounter;
let mainElement = <Form.Control
id = {elementId}
type = {this.state.type}
placeholder = {this.state.placeholder}
maxLength = {this.state.maxlength}
/>
return <Row>
<ModalPanel
handleHide = {this.props.handleHide}
handleShow = {this.props.handleShow}
setLabel = {this.setLabel}
/>
</Row>
}
}
当在ModalPanel
组件中单击按钮时,必须触发旨在设置InputBox
状态的setLabel
功能。问题是,窗口上有多个呈现的
组件,当我尝试使用此功能时,“状态更改”只影响
组件的第一个实例。我想做的是,每个实例都应该有自己的内部状态,并且setLabel()
函数应该绑定到调用它的特定组件。因此,此函数可以设置不同组件实例的状态。我怎么能这么做
添加:
请查看下面的链接以查看显示我的系统如何工作错误的gif图像。正如您所看到的,即使我选择了第三个输入框元素来编辑它的属性(在本例中,设置它的占位符文本),也会对第一个元素进行更改
在开头添加一个
。
,如:
this.setLabel = setLabel.bind(this);
现在您正在InputBox实例上设置一个属性。当您稍后在组件中引用它时,请确保使用this.setLabel引用它 设置标签是否作用于特定的
postID
?是不是每个
的
都作用于同一postID
的问题?因为您在
中未正确使用setLabel
setLabel
接受2个参数,而现在您的实现没有使用任何参数。这是您的单击处理程序
onClick = {() => props.setLabel()}
尝试console.log
ging insetLabel
并查看单击每个按钮时得到的值
function setLabel(postID, attributeName){
console.log(postID, attributeName)
var text = 'example';
if(text !== ''){
this.setState({ [attributeName] : text});
}
}
由于React组件仅根据道具或状态更改进行更新,因此需要将全局状态与本地状态配对以更新组件。在沙箱环境中查看下面的代码
let value = 0;
function updateStuff () {
console.log("this from update", this.name);
value++;
this.setState({name: "Hakan " + value});
}
class Test extends React.Component {
constructor(props){
super(props);
this.state = {
name: 'notchanged',
counter: 1
}
this.localFunc = this.localFunc.bind(this)
updateStuff = updateStuff.bind(this)
}
localFunc(){
let {counter} = this.state;
this.setState({counter: counter + 1});
updateStuff();
}
render () {
return (
<div>
<div>Test 2</div>;
<div>Counter: {this.state.counter}</div>
<div>Name: {this.state.name}</div>
<button onClick={this.localFunc}>Increment</button>
</div>
);
}
}
ReactDOM.render(
<Test/>,
document.getElementById('root')
);
let值=0;
函数updateStuff(){
log(“此来自更新”,此.name);
值++;
this.setState({name:“Hakan”+value});
}
类测试扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
名称:“未更改”,
柜台:1
}
this.localFunc=this.localFunc.bind(this)
updateStuff=updateStuff.bind(此)
}
localFunc(){
设{counter}=this.state;
this.setState({counter:counter+1});
updateStuff();
}
渲染(){
返回(
试验2;
计数器:{this.state.Counter}
名称:{this.state.Name}
增量
);
}
}
ReactDOM.render(
,
document.getElementById('root'))
);
想想看,您使用的反应方式不正确
我喜欢的方式是:
标签
作为属性(在props中,而不是在state中)在绑定函数调用后将其添加到函数调用中,或者使用箭头函数 它仍然只影响我尝试的每个其他实例的第一个实例。它们看起来甚至不像共享相同的状态,其他实例上的任何更改都只会影响第一个实例的状态。请再次检查我的问题,我添加了一个选项。您能否详细说明选择此模式的原因?很可能你不需要它,而试图修复它只会给自己带来更多麻烦
setLabel=setLabel.bind(this)
-这将把setLabel
变量设置为一个新的绑定函数,该函数不能反弹。我将有更多的组件,如“CheckBoxComponent”等。我需要一个全局帮助函数,以避免在每个不同的组件中反复声明相同的函数。这可能不是最好的答案,但是您是否尝试将元素作为第三个参数传递给函数调用,而不是绑定它<例如,代码>函数setLabel(postID、attributeName、element){…element.setState(…)}。另外,您在哪里传递propID
和attributeName
参数?@KawaLo,我没有使用propID,我应该使用它吗?另外,不,我没有尝试你的建议,但它看起来不像是一种反应方式。实际上不是反应,但总的来说你是对的,这不是一种好的继续进行的方式。有一次它为我解决了这个问题,所以我提出了它,但它们是正确的方法(我的意思是绑定)。我会尝试一些东西,也许知道问题出在哪里。对于函数参数,我只是想知道您在哪里设置attributeName
和propID
来更新输入值,因为问题可能就在这里,您能再解释一下吗?OP已经在使用此,但它不起作用。如何在这里使用箭头功能
let value = 0;
function updateStuff () {
console.log("this from update", this.name);
value++;
this.setState({name: "Hakan " + value});
}
class Test extends React.Component {
constructor(props){
super(props);
this.state = {
name: 'notchanged',
counter: 1
}
this.localFunc = this.localFunc.bind(this)
updateStuff = updateStuff.bind(this)
}
localFunc(){
let {counter} = this.state;
this.setState({counter: counter + 1});
updateStuff();
}
render () {
return (
<div>
<div>Test 2</div>;
<div>Counter: {this.state.counter}</div>
<div>Name: {this.state.name}</div>
<button onClick={this.localFunc}>Increment</button>
</div>
);
}
}
ReactDOM.render(
<Test/>,
document.getElementById('root')
);