这是一个简单的例子:
copyButton = <SomeReactComponent title="My Button" />
this.clipboard = new Clipboard('button#copy-button');
this.clipboard.on('success', () => {
this.copyButton.props.title = "Copied!";
});
render = () => {
return (
...
{ this.copyButton }
...
);
}
使用Clipboard.js,当按下我的按钮时,我将一些文本复制到剪贴板。在成功的副本上,我想更改我的复制按钮的标题以反映这一点。我保留引用的按钮组件已经被渲染,this.copyButton.props.title
显然不起作用,因为组件是不可变的。
那么,我会如何更改按钮上title
的值?我知道我可以在父组件中有一个state属性,但我宁愿避免这样做以保持我的父组件完全无状态。我可以简单地在成功回调中重新分配this.copyButton
(我试过但没有运气)?
更一般地说,如果有的话,父组件应如何更新他们孩子的道具?使用国家真的是唯一的方式吗?
注意:如果重要的话,我会使用ES6。
答案 0 :(得分:1)
考虑到您正在尝试更新按钮文本的状态,不使用某种形式的反应状态(在父组件或子组件中)可能会感觉有点hacky。但是,这是可能的。我们想到的最初方法是使用React.cloneElement
创建一个新版本的copyButton
,其中包含您想要的title
道具。然后使用this.forceUpdate
使用update子组件重新呈现父组件。像这样:
this.clipboard.on('success', () => {
this.copyButton = React.cloneElement(this.copyButton, {
title: 'Copied!'
});
this.forceUpdate();
});
https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement
话虽如此,在这种情况下使用state
对于可读性和运行时几乎肯定会更好(克隆元素并强制重新渲染并不便宜)。
答案 1 :(得分:0)
这对我来说并不是很反应。
我想你想做这样的事情:
getInitialState = () => {
return {
title: 'Button Title'
};
};
componentDidMount = () => {
this.clipboard = new Clipboard(this.refs.copyButton);
this.clipboard.on('success', () => {
this.setState({
title: 'Copied!'
})
});
};
componentWillUnmount = () => {
// You should destroy your clipboard and remove the listener
// when the component unmounts to prevent memory leaks
this.clipboard.destroy();
// or whatever the comparable method is for clipboard.js
};
render = () => {
return (
...
<SomeReactComponent ref="copyButton" title={this.state.title} />
...
);
};
最终结果是您的按钮在初始渲染时安装。然后将其ref传递到componentDidMount()
,它会实例化您的剪贴板和success
侦听器。点击您的按钮后,系统会调用this.setState()
来更新按钮组件的内部title
状态,该状态会自动触发使用新标题重新渲染您的组件。
此外,根据React docs,如果可以,您希望尽量避免使用forceUpdate()
。
通常你应该尽量避免使用forceUpdate(),只能在render()中读取this.props和this.state。这使你的组件纯净&#34;并且您的应用程序更加简单和高效。