2017-08-30 50 views
0

在应用程序的很多地方,我们打电话给/search api,你从结果中选择id,然后结果将被丢弃,因为结果是暂时使用的,这使我觉得不值得保存它们甚至派遣行动(除了设置isLoading标志)。但这会迫使我解决反应组件的承诺,是否认为是不好的做法或反模式?React Component中是否考虑了反模式解析承诺?

如:

componentDidMount() { 
    this.props.doSearch(criterias) 
     .then(res => this.setState({ results: res.results })) 
    } 

回答

0

是的,这是ReactJS已知的反模式,因为你不能保证在承诺解决的成分仍然存在。你可以在技术上检查使用this.isMounted,但这也被认为是反模式。

问题是,ReactJS并不是真的被设计成一个全功能的应用程序框架 - 当你真的只是一个V时,你有点推MV MVC。为了最有效,React应该与一些其他库(Redux非常受欢迎)可以存储应用程序数据,然后React可以为您呈现。最好将React视为一个将内部UI状态变为实际UI的库。这对管理状态并不好。

请参阅https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

+0

是的, ,我知道反应是为了视图,这就是为什么我问这个问题。我的问题出现了,因为我觉得,一旦用户选择了ID,我就可以将其存储在商店中,我必须再次清空商店的这一部分,因为这是暂时的,也许还有其他方法可以做到这一点。 – Kossel

0

是的,它是在反应的反模式。组件卸载后可能会执行this.setState({ results: res.results })

最好的方法是将状态(搜索挂起/搜索解析)移出反应组件。您可以利用redux + redux-thunkmobxflux来帮助您。对于简单的情况,你可以建立一个可取消的承诺。

const makeCancelable = (promise) => { 
    let hasCanceled_ = false; 

    const wrappedPromise = new Promise((resolve, reject) => { 
    promise.then(
     val => hasCanceled_ ? reject({isCanceled: true}) : resolve(val), 
     error => hasCanceled_ ? reject({isCanceled: true}) : reject(error) 
    ); 
    }); 

    return { 
    promise: wrappedPromise, 
    cancel() { 
     hasCanceled_ = true; 
    }, 
    }; 
}; 

class MyComponent extends Component { 
    componentDidMount() { 
    this.cancellableSearch = makeCancelable(this.props.doSearch()); 
    this.cancellableSearch.then((res) => { 
     this.setState({ results: res.results }); 
    }).catch((reason) => { 
     if (!isCanceled.isCanceled) { 
     console.error('some error occurs', reason); 
     } 
    }) 
    } 

    componentWillUnmount() { 
    this.cancellableSearch.cancel(); 
    } 

    // ... 
} 

撤销的承诺的代码是从这里复制:https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

+0

我确实在我们的项目中使用了REDX。现在对于我称为搜索API的每个地方,我都必须将结果保存在商店的不同部分,并感觉它是多余的,因为一旦选择了该ID,就不再需要结果 – Kossel