Javascript 每个组件仅获取一次数据
我有一个简单的组件,它获取数据,然后才显示数据:Javascript 每个组件仅获取一次数据,javascript,reactjs,Javascript,Reactjs,我有一个简单的组件,它获取数据,然后才显示数据: class MyComponent extends React.Component { constructor(props) { super(props); this.state = { loaded: false stuff: null }; } componentDidMount() { // load
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false
stuff: null
};
}
componentDidMount() {
// load stuff
fetch( { path: '/load/stuff' } ).then( stuff => {
this.setState({
loaded: true,
stuff: stuff
});
} );
}
render() {
if ( !this.state.loaded ) {
// not loaded yet
return false;
}
// display component based on loaded stuff
return (
<SomeControl>
{ this.state.stuff.map( ( item, index ) =>
<h1>items with stuff</h1>
) }
</SomeControl>
);
}
}
类MyComponent扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
加载:false
内容:空
};
}
componentDidMount(){
//装东西
获取({path:'/load/stuff'})。然后(stuff=>{
这是我的国家({
是的,
东西:东西
});
} );
}
render(){
如果(!this.state.loaded){
//尚未加载
返回false;
}
//基于加载内容的显示组件
返回(
{this.state.stuff.map((项,索引)=>
有东西的东西
) }
);
}
}
MyComponent
的每个实例都从相同的URL加载相同的数据,我需要以某种方式存储这些数据,以避免向服务器重复请求
例如,如果我在页面上有10个MyComponent,那么应该只有一个请求(1个获取)
我的问题是,存储这些数据的正确方法是什么?我应该使用静态变量吗?或者我需要使用两个不同的组件
谢谢你的建议 > P>您应该考虑使用像ReDux这样的状态管理库,在那里您可以存储所有的应用程序状态和需要数据的组件可以订阅。您可以只在应用程序的根组件中调用一次fetch,并且组件的所有10个实例都可以订阅state。如果您想使用react only模拟单个fetch调用。然后,您可以使用react上下文API中的提供者-使用者API。在那里,您只能在提供者中进行一次api调用,并且可以使用组件中的数据
const YourContext = React.createContext({});//instead of blacnk object you can have array also depending on your data type of response
const { Provider, Consumer } = YourContext
class ProviderComponent extends React.Component {
componentDidMount() {
//make your api call here and and set the value in state
fetch("your/url").then((res) => {
this.setState({
value: res,
})
})
}
render() {
<Provider value={this.state.value}>
{this.props.children}
</Provider>
}
}
export {
Provider,
Consumer,
}
At some top level you can wrap your Page component inside Provider. Like this
<Provider>
<YourParentComponent />
</Provider>
In your components where you want to use your data. You can something like this kind of setup
import { Consumer } from "path to the file having definition of provider and consumer"
<Consumer>
{stuff => <SomeControl>
{ stuff.map( ( item, index ) =>
<h1>items with stuff</h1>
) }
</SomeControl>
}
</Consumer>
constYourContext=React.createContext({})//根据响应的数据类型,也可以使用数组代替blacnk对象
const{Provider,Consumer}=YourContext
类ProviderComponent扩展了React.Component{
componentDidMount(){
//在此处进行api调用,并将值设置为state
获取(“您的/url”)。然后((res)=>{
这是我的国家({
价值:res,
})
})
}
render(){
{this.props.children}
}
}
出口{
供应商,
消费者,
}
在某些顶层,您可以将页面组件包装到提供程序中。这样地
在要使用数据的组件中。你可以做类似这样的设置
从“具有提供者和使用者定义的文件路径”导入{Consumer}
{stuff=>
{stuff.map((项,索引)=>
有东西的东西
) }
}
更方便的方法是使用某种状态管理器,如redux或mobx。您也可以探索这些选项。你可以在这里阅读上下文
注意:这是psuedo代码。有关具体实现,请参阅链接
上述
如果要避免使用redux或某种状态管理库,可以导入一个文件,该文件将为您执行抓取操作。沿着这条线的东西。实际上,缓存存储在fetcher.js文件中。导入文件时,实际上并不是每次都将其作为单独的代码导入,因此导入之间的缓存变量是一致的。在第一个请求中,缓存被设置为承诺;在后续请求中,承诺刚刚返回
//fetcher.js
让cache=null;
导出默认函数makeRequest(){
如果(!缓存){
cache=fetch({
路径:'/load/stuff'
});
}
返回缓存;
}
//index.js
从“./fetcher.js”导入fetcher;
类MyComponent扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
加载:false
内容:空
};
}
componentDidMount(){
//装东西
fetcher().then(stuff=>{
这是我的国家({
是的,
东西:东西
});
} );
}
render(){
如果(!this.state.loaded){
//尚未加载
返回false;
}
//基于加载内容的显示组件
返回(
{this.state.stuff.map((项,索引)=>
有东西的东西
) }
);
}
}
您可以使用以下代码将活动请求加入到一个承诺中:
const f = (cache) => (o) => {
const cached = cache.get(o.path);
if (cached) {
return cached;
}
const p = fetch(o.path).then((result) => {
cache.delete(o.path);
return result;
});
cache.set(o.path, p);
return p;
};
export default f(new Map());//use Map as caching
如果您的用例表明页面上可能有10个这样的组件,那么我认为您的第二个选项就是答案——两个组件。一个组件用于获取数据并基于数据呈现子级,第二个组件用于接收数据并呈现数据
这是“智能”和“哑”组件的基础。智能组件知道如何获取数据并对这些数据执行操作,而非智能组件只是简单地呈现给它们的数据。在我看来,您上面指定的组件过于智能,不利于自身 供尝试使用功能组件解决此问题的人员使用 如果您只想获取装载时的数据,那么可以将空数组作为属性添加到
useffect
因此,这将是:
useEffect( () => { yourFetch and set }, []) //Empty array for deps.
您可以将fetch作为组件的依赖项,该组件需要由使用者提供,或者将fetch作为包装器导入,以跟踪活动连接并在一个承诺中加入相同的请求。这不能满足以下要求:“如果我在页面上有10个MyComponent,则应该只有一个请求(1个fetch)”