我创建了一个应用程序来学习 ReactJS。不幸的是,当我尝试使用上下文时,我在渲染时遇到了 1 个错误,但我的应用程序编译良好。
这是我的代码:
import React, {Component} from 'react';
const LoginContext = React.createContext(null);
const user = {
isLoggedIn: true,
username: 'test',
};
class App extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false,
user: user,
};
}
render() {
return (
<LoginContext.Provider user={this.state.user}>
<Welcome/>
</LoginContext.Provider>
);
}
}
class Welcome extends Component {
render() {
return (
<div>
<WelcomeText/>
</div>
);
}
}
class WelcomeText extends Component {
render() {
return (
<LoginContext.Consumer>
<div>
{(user) => (<p>{user.username}</p>)} …Run Code Online (Sandbox Code Playgroud) 我正在使用返回包装组件的 HOC 尝试新的上下文 API。当我使用这种Class.contextType = Context方法时它不起作用:
return function myHOC(WrappedComponent) {
class HOC extends React.Component {
// static contextType = MyContext;
render() {
console.log(this.context); // HERE, this logs `{}`
// ..do stuff
return <WrappedComponent {...this.props} />
}
}
HOC.contextType = MyContext;
return HOC;
};
Run Code Online (Sandbox Code Playgroud)
但是,我制作了相同的代码,但使用<MyContext.Consumer>它并且运行良好:
return function myHOC(WrappedComponent) {
const HOC = (props) => (
<MyContext.Consumer>
{(context) => {
console.log(context); // HERE, correct values
return <WrappedComponent {...props} />
}}
</MyContext.Consumer>
);
return HOC;
};
Run Code Online (Sandbox Code Playgroud)
我在这里没有看到什么吗?
我构建了一个大型应用程序,其中导航栏上的单个按钮打开一个模式。
我正在使用上下文 API 跟踪 modalOpen 状态。
因此,用户单击导航栏上的按钮。模态打开。Modal 有一个名为 QuoteCalculator 的容器。
报价计算器如下所示:
class QuoteCalculator extends React.Component {
static contextType = ModalContext;
// ...
onSubmit = () => {
// ...
this.context.toggleModal();
this.props.history.push('/quote');
// ..
};
render() {
//...
return(<Question {...props} next={this.onSubmit} />;)
}
}
export default withRouter(QuoteCalculator);
Run Code Online (Sandbox Code Playgroud)
现在,一切都按预期进行。当用户提交时,我去正确的路线。我只是在控制台上看到以下警告
index.js:1446 警告:withRouter(QuoteCalculator):函数组件不支持 contextType。
我很想忽略警告,但我认为这不是一个好主意。
我尝试使用重定向替代。所以像
QuoteCalculator looks as follows:
class QuoteCalculator extends React.Component {
static contextType = ModalContext;
// ...
onSubmit = () => {
// ...
this.context.toggleModal();
this.setState({done: true});
// ..
}; …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 SSR 获得反应上下文。这就是我所拥有的
// server/index.s
import express from "express";
import serverRenderer from "./middleware/renderer";
const PORT = 3000;
const path = require("path");
const app = express();
const router = express.Router();
router.use("^/$", serverRenderer);
app.use(router);
app.listen(PORT, error => {
console.log("listening on 3000 from the server");
if (error) {
console.log(error);
}
});
Run Code Online (Sandbox Code Playgroud)
这就是渲染器的样子——
export default (req, res, next) => {
const filePath = path.resolve(__dirname, "..", "..", "..", "index.html");
fs.readFile(filePath, "utf8", (err, htmlData) => {
if (err) {
console.log("err", err);
return res.status(404).end();
}
const store …Run Code Online (Sandbox Code Playgroud) 我使用了一个使用React Hooks的结构。它基于包含减速器组合的全局上下文(如在 Redux 中)。此外,我广泛使用自定义钩子来分离逻辑。我有一个包含异步 API 请求的钩子,它变得非常麻烦,我有机会将这个钩子的几乎每个函数拆分成其他钩子,但是这些函数中的每一个都使用全局上下文(更准确地说 - 从 useReducer() 调度) )。
供应商/Store.js
import React, { createContext, useReducer } from 'react';
export const StoreContext = createContext();
export const StoreProvider = ({ children }) => {
/**
* Store that contains combined reducers.
*/
const store = useReducer(rootReducer, initialState);
return (
<StoreContext.Provider value={store}>{children}</StoreContext.Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
钩子/useStore.js
import { useContext } from 'react';
import { StoreContext } …Run Code Online (Sandbox Code Playgroud) 我只是好奇是否可以在 Context API 中使用 Context API。例如,我将为 AppState 提供一个 Context API,并希望在另一个处理 WebSocket 连接的 Context API 中使用它?
我有以下反应类组件每 10 秒调用一次 API。它的作品没有问题。
class Alerts extends Component {
constructor() {
this.state = {
alerts: {},
}
}
componentDidMount() {
this.getAlerts()
this.timerId = setInterval(() => this.getAlerts(), 10000)
}
componentWillUnmount() {
clearInterval(this.timerId)
}
getAlerts() {
fetch(this.getEndpoint('api/alerts/all"))
.then(result => result.json())
.then(result => this.setState({ alerts: result }))
}
render() {
return (
<>
<ListAlerts alerts={this.state.alerts} />
</>
)
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其转换为反应功能组件。这是我迄今为止的尝试。
const Alerts = () => {
const [alerts, setAlerts] = useState([])
useEffect(() => {
getAlerts()
setInterval(() => getAlerts(), 10000)
}, [])
getAlerts() …Run Code Online (Sandbox Code Playgroud) reactjs react-native react-component react-context react-functional-component
假设我想为“手风琴”(一组可折叠面板)创建一个 UI 组件。父组件控制哪些面板打开的状态,而子面板应该能够读取上下文以确定它们是否打开。
const Accordion = ({ children }) => {
const [openSections, setOpenSections] = useState({})
const isOpen = sectionId => Boolean(openSections[sectionId])
const onToggle = sectionId => () =>
setOpenSections({ ...openSections, [sectionId]: !openSections[sectionId] })
const context = useMemo(() => createContext(), [])
// Can't tell children to use *this* context
return (
<context.Provider value={useMemo(() => ({ isOpen, onToggle }), [isOpen, onToggle])}>
{children}
</context.Provider>
)
}
const AccordionSection = ({ sectionId, title, children }) => {
const { isOpen, onToggle } = …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我使用的是 React Hooks/Context API。现在,每当我的 Provider 组件挂载时,我都需要将从 localStorage 获取的数据分配给 initialState.carts / state.carts。如果 useEffect 支持返回对象,这是可能的。但是不能在 useEffect 中返回对象!
现在我该如何解决这个问题?
代码如下,
const initialState = {
books: books,
carts: []
};
export const Context = createContext(initialState);
export const Provider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
if (localStorage.getItem("carts") !== null) {
const fetchedCarts = JSON.parse(localStorage.getItem("carts"));
//Here I want to assign 'fetchedCarts' array items in 'state.carts' or 'initialState.carts'
}
});Run Code Online (Sandbox Code Playgroud)
我正在使用 React 上下文来保存我的应用程序的身份验证状态。目前,我遇到了一个问题,每当我尝试点击 时/groups/:id,它总是/login首先将我重定向到/UserDash. 发生这种情况是因为我的 AuthProvider 的上下文更新得不够快,而我的私有路由利用 AuthContext 来决定是否重定向。
<AuthProvider>
<Router>
<Switch>
<LoggedRoute exact path = "/" component = {Home}/>
<Route exact path = "/login" component = {Login}/>
<PrivateRoute exact path = "/groups/:id" component = {GroupDash}/>
<PrivateRoute exact path = "/UserDash" component = {UserDash}/>
</Switch>
</Router>
</AuthProvider>
Run Code Online (Sandbox Code Playgroud)
在另一个文件中:
export const AuthContext = React.createContext();
export const AuthProvider = ({children}) => {
const [currentUser, setCurrentUser] = useState(null);
useEffect(() => {
firebaseApp.auth().onAuthStateChanged(setCurrentUser);
},[]);
return (
<AuthContext.Provider
value …Run Code Online (Sandbox Code Playgroud) firebase reactjs react-router firebase-authentication react-context
react-context ×10
reactjs ×10
javascript ×4
react-hooks ×2
react-native ×2
react-router ×2
firebase ×1
rendering ×1
use-reducer ×1
websocket ×1