如何在不必将父组件与所有这些提供程序包装在一起的情况下简化React Context API提供程序?我有几个页面:主页,博客,联系人,图库和关于。我已经为联系页面创建了一个Context API Context和Provider。每个供应商都有自己独特的API,我正在使用带有React Hooks的Axios来获取。
我要问的是有一种方法可以保持我的代码干净整洁,而不是一遍又一遍地重复自己。
例如,我想要一个Context函数,可以一遍又一遍地使用它,并且只能获取一个唯一的Axios API URL的API数据。
我该怎么做?复制粘贴相同的东西..不干净。
PageContext.js:
import React, { useState, useEffect, createContext } from 'react';
import axios from 'axios';
import PropTypes from 'prop-types';
import { PAGE_CONTACT } from 'constants/import';
export const PageContext = createContext();
export const PageProvider = props => {
const [contactPage, setContactPage] = useState([]);
useEffect(() => {
axios.get(PAGE_CONTACT).then(result => setContactPage(result.data));
}, []);
return (
<PageContext.Provider value={[contactPage, setContactPage]}>
{props.children}
</PageContext.Provider>
);
};
PageProvider.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
};
我使用上下文的页面联系人(组件):
import React, { useContext } from 'react';
import ReactHtmlParser from 'react-html-parser';
import { PageContext } from 'pages/context/PageContext';
const Contact = () => {
const [field] = useContext(PageContext);
return (
<section className="contact">
<div className="page">
<div className="row">
<div className="col-xs-12">
<h3 className="section__title">{field.page_title}</h3>
{ReactHtmlParser(field.page_content)}
{field.page_featured_image && (
<img src={field.page_featured_image.path} />
)}
</div>
</div>
</div>
</section>
);
};
export default React.memo(Contact);
Index.js与提供程序包装在一起:
import React from 'react';
import ReactDOM from 'react-dom';
import { PageProvider } from 'pages/context/PageContext';
// Styles
import 'sass/root.scss';
// Root App
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<PageProvider>
<App />
</PageProvider>,
document.getElementById('root')
);
serviceWorker.unregister();
答案 0 :(得分:0)
这是一种有趣的方法,我个人不会将上下文用于您的解决方案。
我这样做的原因是,使用提供程序意味着您希望每个反应value
道具都可以访问此children
道具(这对于联系页面没有意义)。
我只能假定您的联系页面将具有仅该页面所需的内容?如果是这样,请做一些思考:
联系页面:
import React, { useState, useEffect } from "react";
import axios from "axios";
import ReactHtmlParser from "react-html-parser";
const Contact = () => {
const [pageData, setPageData] = useState();
useEffect(() => {
axios.get(PAGE_CONTACT).then(result => {
// Axios - check success!
if (result.meta === 200) {
setPageData(result.data);
}
});
// You should be doing error handling here as well!
}, []);
return (
<section className="contact">
<div className="page">
<div className="row">
<div className="col-xs-12">
{!!pageData ? (
<>
<h3 className="section__title">{pageData.page_title}</h3>
{ReactHtmlParser(pageData.page_content)}
{pageData.page_featured_image && (
<img src={pageData.page_featured_image.path} />
)}
</>
) : (
<p>Some loading UI...</p>
)}
</div>
</div>
</div>
</section>
);
};
export default Contact;
我要说的是,这里的关键是要问您使用反应上下文的意图。将其添加到主要组件后,当值更改时将触发dom的重新渲染。
您可能拥有不依赖于联系页面的UX,例如关于页面。