假设我有这些组件:
Translator
TranslationList
Translator
确定翻译上下文,具有翻译功能。
TranslationList
必须显示这些“视觉状态”:加载,结果列表,没有结果。
Translator
在页面周围移动(一个实例):在对输入进行聚焦时,它会在“下方”移动并给出一个带有建议的下拉列表。
因此,每次移动时,都必须:
所以我的问题是:
哪个组件应该控制“加载”视觉状态?
如果Translator
组件控制它,则必须将loading=true translations=[]
作为道具传递给Translation
列表。然后它必须使用新道具loading=false translations=[...]
再次重新渲染它。这似乎有点违反直觉,因为loading
感觉就像TranslationList
组件的状态。
如果我们TranslationList
组件有loading
状态,那么它还必须有translate
个方法,这意味着我必须通过translate
函数作为道具。然后我会将translations
和loading
作为状态。这一切都变得有点混乱,因为现在它必须还接收要翻译的字符串,上下文。
我也不希望有单独的组件来加载消息,没有结果消息。我宁愿将这些保留在TranslationList
内,因为这3个共享相同的包装<div class="list-group"></div>
也许在这两个组件之间应该还有一个组件,只负责提取翻译数据?
答案 0 :(得分:2)
转换程序组件应控制较低组件列表组件的加载状态。保持加载和转换逻辑,但在帮助下将它包装在一个高位组件中,你应该放置大部分逻辑。链接HOC https://www.youtube.com/watch?v=ymJOm5jY1tQ。
const translateSelected = wrappedComponent =>
//return Translator component
class extends React.Component {
state = {translatedText: [], loading:true}
componentDidMount(){
fetch("text to translate")
.then(transText => this.setState({translatedText: transText, loading: false}))
}
render() {
const {translatedText} = this.state
return <WrappedComponent {..this.props} {...translatedText}
}
}
const Translator_HOC = translateSelected(Translator);
&#13;
答案 1 :(得分:2)
您可以引入更高阶组件来控制加载状态和TranslationList
的切换。这样您就可以将加载显示与TranslationList分开,因为它是关注的问题。这也允许您在其他区域使用HOC。
Translator
可以作为“容器”组件来执行数据提取/传递。
例如:
// The Loadable HOC
function Loadable(WrappedComponent) {
return function LoadableComponent({ loaded, ...otherProps }) {
return loaded
? <WrappedComponent {...otherProps} />
: <div>Loading...</div>
}
}
// Translation list doesn't need to know about "loaded" prop
function TranslationList({ translations }) {
return (
<ul>
{
translations.map((translation, index) =>
<li key={index}>{translation}</li>
)
}
</ul>
)
}
// We create our new composed component here.
const LoadableTranslationList = Loadable(TranslationList)
class Translator extends React.Component {
state = {
loaded: false,
translations: []
}
componentDidMount() {
// Let's simulate a data fetch, typically you are going to access
// a prop like this.props.textToTranslate and then pass that to
// an API or redux action to fetch the respective translations.
setTimeout(() => {
this.setState({
loaded: true,
translations: [ 'Bonjour', 'Goddag', 'Hola' ]
});
}, 2000);
}
render() {
const { loaded, translations } = this.state;
return (
<div>
<h3>Translations for "{this.props.textToTranslate}"</h3>
<LoadableTranslationList loaded={loaded} translations={translations} />
</div>
)
}
}
ReactDOM.render(<Translate textToTranslate="Hello" />)