注意:根据Nicholas Tower的回答,我在做出更改后对问题进行了编辑。
我有一个绑定到组件并更改其状态的全局函数。
我想构建一个表单生成器系统。有一个名为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
组件函数,其中触发了setLabel
函数。
function ModalPanel(props){
return(
......................
......................
......................
<Button variant="primary" onClick = {() => props.setLabel()}>Save changes</Button>
......................
......................
......................)
}
在setLabel
组件中单击按钮时,必须触发旨在设置InputBox
状态的 ModalPanel
函数。问题是,窗口上有多个呈现的<InputBox />
组件,当我尝试使用此功能时,“状态更改”仅影响<InputBox />
组件的第一个实例。我想做的是,每个实例都应该有自己的内部状态,setLabel()
函数应该绑定到调用它的特定组件。因此,该功能可以设置不同组件实例的状态。我该怎么办?
添加:
请检查下面的链接,以查看gif图片,显示我的系统工作方式错误。如您所见,即使我选择了第三个输入框元素来编辑其属性(在本例中,将其设置为占位符文本),对第一个输入框也进行了更改。
答案 0 :(得分:3)
在开头添加this.
,如下所示:
this.setLabel = setLabel.bind(this);
现在,您要在InputBox实例上设置属性。稍后在组件中引用它时,请确保使用this.setLabel对其进行引用。
答案 1 :(得分:0)
setLabel
是否在执行特定的postID
?是每个<Button />
中的<ModalPanel />
都作用于同一postID
的问题吗?因为您没有在setLabel
内部正确使用<ModalPanel />
。 setLabel
接受2个参数,现在您的实现未使用任何参数。这是您的点击处理程序。
onClick = {() => props.setLabel()}
尝试console.log
内的setLabel
并查看单击每个按钮时得到的值
function setLabel(postID, attributeName){
console.log(postID, attributeName)
var text = 'example';
if(text !== ''){
this.setState({ [attributeName] : text});
}
}
答案 2 :(得分:0)
由于React组件仅通过props或状态更改进行更新,因此您需要将全局状态与本地状态配对以更新组件。在沙盒环境中,请参见下面的代码。
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')
);
答案 3 :(得分:0)
认为,您使用React的方式不正确
对我来说首选方式如下:
label
作为属性(在道具中,不在状态中)答案 4 :(得分:-1)
在绑定它们或使用箭头函数后,将其添加到您的函数调用中!