Gus*_*nça 61 reactjs react-context
我正在使用新的React Context API而不是Redux开发一个新的应用程序,之前,Redux当我需要获取用户列表时,我只需调用componentDidMount我的操作,但现在使用React Context,我的操作就在里面我的消费者在我的渲染函数中,这意味着每次调用我的渲染函数时,它都会调用我的动作来获取我的用户列表,这是不好的,因为我会做很多不必要的请求.
那么,我怎么只能调用一次我的动作,比如componentDidMount不是在渲染中调用?
举个例子,看看这段代码:
让我们假设我将所有内容包装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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
然后我把这个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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在我的用户视图中,它将是这样的:
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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
我想要的是这个:
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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
但是当然上面的例子不起作用,因为getUsers不住在我的用户视图道具中.如果可以的话,这样做的正确方法是什么?
Shu*_*tri 96
编辑:通过在v16.8.0中引入react-hooks ,您可以通过使用useContext钩子在功能组件中使用上下文
const Users = () => {
const contextValue = useContext(UserContext);
// rest logic here
}
Run Code Online (Sandbox Code Playgroud)
编辑:从版本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
Run Code Online (Sandbox Code Playgroud)
在版本16.6.0之前,您可以通过以下方式执行此操作
为了在你的lifecyle方法中使用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>
)
Run Code Online (Sandbox Code Playgroud)
通常,您将在App中维护一个上下文,将上述登录包装在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>
);
};
};
Run Code Online (Sandbox Code Playgroud)
然后你可以像使用它一样
export default withUserContext(User);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33060 次 |
| 最近记录: |