我有以下反应组件(它可以工作),但我使用cb作为setState。
我想知道如何重构从代码中删除cb的代码:
this.setState({ viewer: null, document: null }, () => this.getViewer(type, item))
export class DocumentComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
document: null,
viewer: null,
}
}
getViewer(type, item) {
let node = null
switch (type) {
case 'image':
node = (
<Imager url={item.src} />
)
this.setState({ viewer: node, document: item })
break
default:
this.setState({ viewer: null, document: null })
return null
}
}
openViewer(type, item) {
this.setState({ viewer: null, document: null }, () => this.getViewer(type, item))
}
handlerOnClick(item: Object) {
this.openViewer('image', item)
}
render() {
const { tileData, classes } = this.props
return (
<div className={classes.root}>
<Thumbnailss tileData={tileData} handlerOnClick={item => this.handlerOnClick(item)} />
{this.state.viewer}
</div>
)
}
}
export default DocumentComponent
&#13;
答案 0 :(得分:3)
为什么不这样?
不是将UI元素存储在状态中,而是存储您要使用的数据,例如src并在您的案例中键入。从render中调用getViewer
方法将返回正确的ui项。通过这种方式你不需要担心setState回调,每当你更新type和src的值时,react会自动更新ui。
export class DocumentComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
src: '',
type: '',
}
}
getViewer() {
switch (this.state.type) {
case 'image': return <Imager url={this.state.src} />
default: return null
}
}
handlerOnClick(item: Object) {
this.setState({
type: 'image',
src: item.src
})
}
render() {
const { tileData, classes } = this.props
return (
<div className={classes.root}>
<Thumbnailss tileData={tileData} handlerOnClick={item => this.handlerOnClick(item)} />
{this.getViewer()}
</div>
)
}
}
export default DocumentComponent
答案 1 :(得分:2)
我认为/你认为你正在使用babel和ES7。如果是这样,您可以使用async
代替。
使用cb
openViewer(type, item) {
this.setState({ viewer: null, document: null }, () => this.getViewer(type, item))
}
使用async-await
async openViewer(type, item) {
await this.setState({ viewer: null, document: null });
this.getViewer(type, item)
}
我们测试了这种方法,它在我们的环境中运行良好。
使用承诺
或者如果你对承诺感到满意。
export class DocumentComponent extends React.Component {
// override and extend setState
setState(state) {
return new Promise((resolve) => {
super.setState(state, resolve);
});
}
//...
//...
openViewer(type, item) {
this.setState({ viewer: null, document: null })
.then(() => this.getViewer(type, item))
}
}
答案 2 :(得分:0)
试试这个:
setViewer(type, item) {
switch (type) {
case 'image':
const node = (
<Imager url={item.src} />
);
this.setState({ viewer: node, document: item });
break;
default:
this.setState({ viewer: null, document: null });
}
}
openViewer(type, item) {
this.setViewer(type, item);
}