我正在使用新的React Context
API而非Redux开发一个新应用,并且在使用之前,例如Redux
,当我需要获取用户列表时,我只是调用componentDidMount
我的操作,但是现在使用React
Context,我的操作可以在内部进行。我的使用者位于我的渲染函数中,这意味着每次调用我的渲染函数时,它将调用我的操作以获取用户列表,这不好,因为我将执行许多不必要的请求。
那么,我怎么只能一次调用动作,例如in componentDidMount
而不是调用render?
只是为了举例说明,请看下面的代码:
假设我将所有内容包装Providers
在一个组件中,如下所示:
import React from 'react';
import UserProvider from './UserProvider';
import PostProvider from './PostProvider';
export default class Provider extends React.Component {
render(){
return(
<UserProvider>
<PostProvider>
{this.props.children}
</PostProvider>
</UserProvider>
)
}
}
然后,我将这个Provider组件包装了所有应用程序,如下所示:
import React from 'react';
import Provider from './providers/Provider';
import { Router } from './Router';
export default class App extends React.Component {
render() {
const Component = Router();
return(
<Provider>
<Component />
</Provider>
)
}
}
现在,以我的用户视图为例,它将是这样的:
import React from 'react';
import UserContext from '../contexts/UserContext';
export default class Users extends React.Component {
render(){
return(
<UserContext.Consumer>
{({getUsers, users}) => {
getUsers();
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}}
</UserContext.Consumer>
)
}
}
我想要的是:
import React from 'react';
import UserContext from '../contexts/UserContext';
export default class Users extends React.Component {
componentDidMount(){
this.props.getUsers();
}
render(){
return(
<UserContext.Consumer>
{({users}) => {
getUsers();
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}}
</UserContext.Consumer>
)
}
}
但是,当然上面的示例不起作用,因为getUsers
不存在于我的用户视图中的道具。如果可能的话,正确的方法是什么?
编辑: 随着 v16.8.0中 引入react-hooks
,您可以通过使用useContext
钩子在功能组件中使用上下文
const Users = () => {
const contextValue = useContext(UserContext);
// rest logic here
}
编辑: 从版本 16.6.0 起。您可以通过使用上下文的生命周期的方法this.context
一样
class Users extends React.Component {
componentDidMount() {
let value = this.context;
/* perform a side-effect at mount using the value of UserContext */
}
componentDidUpdate() {
let value = this.context;
/* ... */
}
componentWillUnmount() {
let value = this.context;
/* ... */
}
render() {
let value = this.context;
/* render something based on the value of UserContext */
}
}
Users.contextType = UserContext; // This part is important to access context values
在版本16.6.0之前,您可以按以下方式进行操作
为了在您的生命周期方法中使用Context,您可以将组件编写为
class Users extends React.Component {
componentDidMount(){
this.props.getUsers();
}
render(){
const { users } = this.props;
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}
}
export default props => ( <UserContext.Consumer>
{({users, getUsers}) => {
return <Users {...props} users={users} getUsers={getUsers} />
}}
</UserContext.Consumer>
)
通常,您将在您的应用程序中维护一个上下文,将上述登录名打包在HOC中以便重新使用是有意义的。你可以这样写
import UserContext from 'path/to/UserContext';
const withUserContext = Component => {
return props => {
return (
<UserContext.Consumer>
{({users, getUsers}) => {
return <Component {...props} users={users} getUsers={getUsers} />;
}}
</UserContext.Consumer>
);
};
};
然后你可以像这样使用它
export default withUserContext(User);
问题内容: 快速提问。我正在学习React JS。 创建组件时,我们在render函数中提供要渲染的组件的html模板。到目前为止,我只看到带有很少部分html的小型组件,但是我只是想知道如果我们的组件带有巨大的html模板会发生什么情况,有没有办法提供指向单独的html文件的路径?还是我们被迫直接在render函数中编写所有html?谢谢! 问题答案: 您应该始终将其编写在render函数中。您
问题内容: 我试图更新类“ var CurrentStatus:status!”内的变量,状态是一个枚举。我有一个firebase函数,它将更新变量。变量在firebase函数内部获取更新,但不会在firebase函数外部更新变量 问题答案: 同意杰伊的评论。您无法返回那样的状态,因为Firebases异步工作…我要做的是添加一个闭包参数,该参数在完成时执行,如下所示: class signUpC
我遇到了这个简单的React函数组件,它渲染四次,而我希望它最初渲染一次,执行useffect更新状态,然后再次渲染。相反,控制台发送4个日志输出,表示它渲染了4次。了解react功能组件的基本生命周期的原因和资源吗? https://codesandbox.io/s/solitary-tree-t120d?file=/src/App.js:149-191
问题内容: 最近,我问了一个问题,其中有一个很明显的答案。我仍在同一个项目上,遇到另一个问题。我需要实现每帧逻辑,并且该协议在iOS上工作得很好,但是在OSX上,该功能未触发。我创建了一个小示例项目来说明我的问题。它由情节提要中的Scene Kit视图和该类中的以下代码组成: 我想要的基本上是每帧移动立方体。但是什么也没发生。什么是奇怪的是,当我设置到时,每当我点击或在屏幕上拖动(这是有道理的,因
在上文中,我们从多个角度讨论了如何优化页面加载性能。但一个用户体验良好的页面,不仅要快速加载,还需要有一系列流畅的交互。从而,这一节我们把目光投向页面渲染性能。 渲染流程 浏览器在渲染页面前,首先会将 HTML 文本内容解析为 DOM,将 CSS 解析为 CSSOM。DOM 和 CSSOM 都是树状数据结构,两者相互独立,但又有相似之处。DOM 树描述了 HTML 标签的属性,以及标签之间的嵌套关
问题内容: 我该如何做出反应渲染呢? 问题答案: 大写字母“ C” 。在React文档中提到了这一点: https://facebook.github.io/react/docs/tags-and- attributes.html