我正在尝试使用新的React上下文来保存有关已登录用户的数据.
为此,我在一个名为的文件中创建一个上下文 LoggedUserContext.js:
import React from 'react';
export const LoggedUserContext = React.createContext(
);
Run Code Online (Sandbox Code Playgroud)
当然,现在我可以使用消费者访问其他组件中的所述上下文,就像我在这里所做的那样:
<LoggedUserContext.Consumer>
{user => (
(LoggedUserContext.name) ? LoggedUserContext.name : 'Choose a user or create one';
)}
</LoggedUserContext.Consumer>
Run Code Online (Sandbox Code Playgroud)
但显然,为了使这个系统有用,我需要在登录后修改我的上下文,这样它就可以保存用户的数据.我正在使用axios调用REST API,我需要将检索到的数据分配给我的上下文:
axios.get(`${SERVER_URL}/users/${this.state.id}`).then(response => { /*What should I do here?*/});
Run Code Online (Sandbox Code Playgroud)
我认为在React的文档中没有办法做到这一点,但他们甚至提到保存登录用户的信息是他们为上下文考虑的用例之一:
Context旨在共享可被视为React组件树的"全局"数据,例如当前经过身份验证的用户,主题或首选语言.例如,在下面的代码中,我们手动穿过"主题"道具来设置Button组件的样式:
那我该怎么办呢?
以下内容适用于NextJS的SSR.
我正在使用React的上下文来跟踪某些已安装组件的ID.要点是
class Root extends React.Component {
getChildContext () {
return {
registerComponent: this.registerComponent
}
}
registerComponent = (id) => {
this.setState(({ mountedComponents }) => {
return { mountedComponents: [...mountedComponents, id ] }
})
}
...
}
class ChildComponent {
static contextTypes = { registerComponent: PropTypes.func }
constructor(props) {
super(props)
props.registerComponent(props.id)
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这只适用于客户端.this.state.mountedComponents总是[]在服务器上.是否有另一种方法来跟踪服务器端的这些组件?基本上我需要使用id来提供脚本以在head文档中运行- 等到客户端应用程序安装,运行并手动附加到头部有点太慢.
更新
这里有一个简单的例子:https://github.com/tills13/nextjs-ssr-context
this.context是undefined在构造函数中Child,如果我将其移动到componentDidMount(当前在repo中以这种方式设置),它可以工作,但我希望这可以在服务器端解析.我没有死定context,如果有另一种方法可以做到这一点,我全都听见了.
在这里做出反应并尝试将新的Context API包裹住(我还没有研究Redux等)。
似乎我可以做很多我需要做的事情,但是最终我将得到很多提供程序,所有提供程序都需要一个标签来包装我的主应用程序。
我将要为Auth提供一个提供程序,一个为主题提供程序,一个为聊天消息提供程序(通过Pusher.com访问),等等。另外使用React Router的是另一个包装元素。
我要结束这个(还有更多)吗?
<BrowserRouter>
<AuthProvider>
<ThemeProvider>
<ChatProvider>
<App />
</ChatProvider>
</ThemeProvider>
</AuthProvider>
</BrowserRouter>
Run Code Online (Sandbox Code Playgroud)
或者,还有更好的方法?
如果你有一个 Redux 应用程序,你想迁移到新的 React Context API + hooks (useReducer),你将如何替换 redux-saga 或 redux-thunk 来处理副作用?我们以 redux-saga 的 github 页面为例:
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
function* mySaga() {
yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}
function* mySaga() {
yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}
export default mySaga;
Run Code Online (Sandbox Code Playgroud)
在没有 Redux 的情况下执行等效操作,而是使用 React Context api …
当前行为
我有一个使用react-navigationv5 进行路由的本机应用程序。
由于(1),我的结构是drawerNavigator (a) > stackNavigator (b) > views (c).
当我尝试useNavigation()在 my 中调用钩子时<DrawerContent />,出现以下错误:
Error: We couldn't find a navigation object. Is your component inside a navigator?
at useNavigation (bundle.js:8766)
Run Code Online (Sandbox Code Playgroud)
是的,我不在里面,stackNavigator所以无法调用钩子
预期行为
我希望在我的<DrawerContent />.
您的环境
| software | version |
| ------------------------------ | ------- |
| iOS or Android | iOS, Android and web
| @react-navigation/native | 5.0.0-alpha.41
| @react-navigation/stack | …Run Code Online (Sandbox Code Playgroud) javascript reactjs react-native react-navigation react-context
我是 React Router 的新手,并尝试使用新的 Conext API 从提供程序内部进行重定向。基本上我的提供者看起来像这样。
/* AuthContext.js */
class AuthProvider extends React.Component {
state = { isLoggedIn: false }
constructor() {
super()
this.login = this.login.bind(this)
this.logout = this.logout.bind(this)
}
login() {
this.setState({ isLoggedIn: true })
// Need to redirect to Dashboard Here
}
logout() {
this.setState({ isLoggedIn: false })
}
render() {
return (
<AuthContext.Provider
value={{
isLoggedIn: this.state.isLoggedIn,
login: this.login,
logout: this.logout
}}
>
{this.props.children}
</AuthContext.Provider>
)
}
}
const AuthConsumer = AuthContext.Consumer
export { AuthProvider, AuthConsumer } …Run Code Online (Sandbox Code Playgroud) 所以,我有两个组件,一个组件始终是另一个组件的直系后代。我想将道具从父组件传递给子组件。可能有多个子组件。有两种方法可以实现它。
React.Children.map(children, (child) =>
React.cloneElement(child, { someProp: 'value' })
)
Run Code Online (Sandbox Code Playgroud)
或使用上下文 API
<Context.Provider value={{ someProp: 'value' }}>
{this.props.children}
</Context.Provider>
Run Code Online (Sandbox Code Playgroud)
两者都会产生相同的 DOM 结构,但是 Context API 的代码稍微多一些,并且会产生更多的 React 组件。
那么哪一款更注重性能,值得推荐。我找不到与此比较相关的任何讨论,因此在这里询问。
我试图迁移react-redux v5.X.X到v6.0.0该站点,似乎没有任何文档。我正在使用以下版本:
"react": "^16.4.2"
"redux": "^4.0.0"
"react-redux": "^6.0.0"
官方更改日志说。
不再支持将存储作为道具传递给已连接的组件。相反,您可以向和都传递自定义context = {MyContext}属性。您也可以通过{context:MyContext}作为连接选项。链接在这里
这是我的根 index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { configureStore, history } from './Store';
import App from './App.hot';
import 'antd/dist/antd.min.css';
const reduxStore = configureStore();
ReactDOM.render(<App store={reduxStore} history={history} />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
这是我的app.jsx(根组件)
import React from 'react';
import PropTypes from 'prop-types';
import { Provider, connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ConnectedRouter } from 'connected-react-router';
import …Run Code Online (Sandbox Code Playgroud) 如果用户经过身份验证并可以通过React Context API访问它,我想保存一个简单的布尔值 + userID 。
许多指南用上下文提供者包装了他们的根组件。对我来说,包装整个应用程序似乎很浪费。另一方面,我需要在我的所有主页中提供此信息。
用 React Context Provider 包装整个应用程序会产生负面影响吗?
例子:
class App extends Component {
render() {
return (
<MyProvider>
<div className="App">
<h1 className="App-title">Welcome to my web store</h1>
<ProductList />
</div>
</MyProvider>
);
}
Run Code Online (Sandbox Code Playgroud)
}
我使用本指南作为参考。
我没有任何 React Redux 经验,所以这对于以前使用过这个框架的每个人来说可能都很自然。
研究 Google 后发现了许多关于如何实现 React Context 或使用 HOC 的指南,但我点击的 15 个指南并没有回答我的问题。
我将Gatsby用作静态网站生成器。我使用React Context API来存储用户已通过身份验证的信息。
在开发模式下,当我键入任何重定向到404错误页面的URL时,上下文数据将丢失。当我导航到有效页面时,以前登录的用户不再登录。
我之前从未使用过React Context,所以不确定如何处理。那是预期的行为吗?有什么方法可以保留用户特定的React Context?我是否需要从后端重新提供上下文?还是我只是犯了一个错误?最好的行动方针是什么?
我想以某种方式将上下文保留在浏览器中,直到会话超时。尚未执行来自后端的会话处理。
编辑:我刚刚用gatsby构建和gatsby服务测试了这一点。当重定向到404错误页面时,内置的gatsby网站会保留上下文。但是,当导航到完全不同的URL(例如www.google.com)时,上下文仍然丢失。
现在我的问题是:如何在不让用户再次手动登录的情况下为上下文提供登录信息?Cookie检查?抱歉,如果我要问一个明显的问题。我从未实现过会话或cookie。
这是我的AuthContextProvider包装器类:
import React from "react";
export const AuthContext = React.createContext();
export class AuthContextProvider extends React.Component {
state = {
authenticated: false,
toggleLogin: () => {},
userid: null,
};
render() {
return (
<AuthContext.Provider
value={{
authenticated: this.state.authenticated,
userid: this.state.userid,
toggleLogin: () => {
const previousValueState = this.state.authenticated;
this.setState(state => ({
authenticated: !previousValueState,
userid: 2,
}));
},
}}
>
{this.props.children}
</AuthContext.Provider>
);
}
}
Run Code Online (Sandbox Code Playgroud)
我用Context Provider将整个应用程序包装在根布局中:
export default function RootLayout({ …Run Code Online (Sandbox Code Playgroud) react-context ×10
reactjs ×10
javascript ×4
gatsby ×1
nextjs ×1
performance ×1
react-native ×1
react-redux ×1
react-router ×1